self.ticksToPixelRatio=128*3*5#bigger value means less space between notes #api.D128 and 128*3*5 is also good. This gets changed during runtime as "Stretch Factor". Also: the QSettings save and reload this on a per-file basis.
#a quarter note has 53760 ticks. that is 53760 / 1920 = 28 pixels.
self.stafflineGap=7#it is 7 because it is an odd number, which has a middle. 123 4 567 which translates 1:1 to pixels.
@ -35,144 +39,12 @@ class ConstantsAndConfigs(object):
self.negativeMagicPixel=-2
self.trackHeight=self.stafflineGap*10
self.trackHeight=self.stafflineGap*12
self.gridRhythm=api.D4#Default value is quarter. The QSettings save and reload this on a per-file basis.
self.gridOpacity=0.1#this is only the default value. Once changed a QSetting will be used instead.
self.noteHeadMode=True#False means rectangle noteheads
self.followPlayhead=True#camera follows the playhead during playback.
self.duringPlayback=False#set by a callback.
self.velocityToPixelRatio=2#2.0 is the default. 128 pixels maximum.
self.noteHeadMode=True#False means rectangle noteheads
self.availableEditModes=("notation","cc","block")
self.ccViewValue=0#0-127. Only has effect if ccView is True
self.ccViewCallbacks=[]#list of functions. For example the main Window CC spin box and the block Editor CC spin box.
self._snapToGrid=True# For CC point and Tempo point placements
self.snapToGridCallbacks=[]# see ccViewCallbacks
self.zoomFactor=1# #Initial Zoom Level. Also hardcoded into scoreView.zoomNull
self.maximumZoomOut=0.25
#fonts which are used in the QGraphicsScenes. They are special because they don't scale with the DPI.
@ -126,30 +124,6 @@ class MainWindow(TemplateMainWindow):
self.scoreView.scoreScene.grid.redrawTickGrid()#Init the grid only after everything got loaded and drawn to prevent a gap in the display. #TODO: which might be a bug. but this here works fine.
api.callbacks.setCursor.append(self.centerOnCursor)#returns a dict
api.callbacks.updateBlockTrack.append(self.updateMode)# We need this after every update because the track is redrawn after each update and we don't know what to show
self.xFactor=1#keep track of the x stretch factor.
self.gapVertical=constantsAndConfigs.gridRhythm/constantsAndConfigs.ticksToPixelRatio#this is necessarry every time after stretching (ticksToPixelRatio) and after changing the gridRhythm
foriinrange(start,end):#range includes the first value but not the end. We know that and all functions in GuiGrid are designed accordingly. For example reactToLongerDuration starts on the highest value of the old number of lines since that was never drawn in the last round.
foriinrange(start,end):#range includes the first value but not the end. We know that and all functions in GuiGrid are designed accordingly. For example reactToMoreTracks starts on the highest value of the old number of lines since that was never drawn in the last round.
#it is possible that the grid did not change. proceed nevertheless
forlinself.linesHorizontal+self.linesVertical:
self.parent.removeWhenIdle(l)
self.linesHorizontal=[]#like the staff lines
self.linesVertical=[]#makes comparing tick positions easier by eye
self.gapVertical=constantsAndConfigs.gridRhythm/constantsAndConfigs.ticksToPixelRatio#this is necessarry every time after stretching (ticksToPixelRatio) and after changing the gridRhythm
self.nrOfHorizontalLines=int(self.height/self.gapHorizontal)#we save that value if the score grows and we need more lines. Initially we use the screen size, not the content.
self.nrOfVerticalLines=int(self.width/self.gapVertical)#we save that value if the score grows and we need more lines. Initially we use the screen size, not the content.
@ -145,61 +144,7 @@ class TickWidget(QtWidgets.QDialog):
self.ui.durationLabel.setText(" + ".join(text))
#There are two types of submenus in this file. The majority is created in menu.py during start up. Like Clef, KeySig etc. These don't need to ask for any dynamic values.
#The other is like SecondaryTempoChangeMenu. In menu.py this is bound with a lambda construct so a new instance gets created each time the action is called by the user. Thats why this function has self.__call__ in its init.
classSubmenu(QtWidgets.QDialog):
#TODO: instead of using a QDialog we could use a QWidget and use it as proxy widget on the graphic scene, placing the menu where the input cursor is.
def__init__(self,mainWindow,labelString):
super().__init__(mainWindow)#if you don't set the parent to the main window the whole screen will be the root and the dialog pops up in the middle of it.
#self.setModal(True) #we don't need this when called with self.exec() instead of self.show()
self.layout=QtWidgets.QFormLayout()
#self.layout = QtWidgets.QVBoxLayout()
self.setLayout(self.layout)
label=QtWidgets.QLabel(labelString)#"Choose a clef" or so.
self.layout.addWidget(label)
#self.setFocus(); #self.grabKeyboard(); #redundant for a proper modal dialog. Leave here for documentation reasons.
self.opacity.valueChanged.connect(lambda:self.mainWindow.scoreView.scoreScene.grid.setOpacity(self.opacity.value()/100))#only react to changes after the initial value was set.
self.opacity.valueChanged.connect(lambda:self.mainWindow.scoreView.scoreScene.grid.setOpacity(self.opacity.value()/100))#only react to changes after the initial value was set.