#! /usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Copyright 2019 , Nils Hilbricht , Germany ( https : / / www . hilbricht . net )
This file is part of the Laborejo Software Suite ( https : / / www . laborejo . org ) ,
more specifically its template base application .
Laborejo2 is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : / / www . gnu . org / licenses / > .
"""
import logging ; logging . info ( " import {} " . format ( __file__ ) )
import engine . api as api
from PyQt5 import QtGui
class ConstantsAndConfigs ( object ) :
def __init__ ( self ) :
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.
self . beamHeight = 2
self . magicPixel = 4
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 . 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.
self . fontDB = QtGui . QFontDatabase ( )
#fid = self.fontDB.addApplicationFont("gui/resources/freesans.ttf")
#if fid == -1:
# raise ValueError("Freesans.ttf not loaded ")
fid = self . fontDB . addApplicationFont ( " :euterpe.ttf " )
if fid == - 1 :
raise ValueError ( " euterpe.ttf not loaded. Make sure resources were generated " )
#For easier programWide access move these to constantsAndConfigs
#constantsAndConfigs.theFont = self.fontDB.font("FreeSans", "", 13)
#constantsAndConfigs.theFont.setPixelSize(13) #It is very important to set the pixel size before setting the font to the text
self . musicFont = self . fontDB . font ( " Euterpe " , " " , 13 )
self . musicFont . setPixelSize ( 13 ) #It is very important to set the pixel size before setting the font to the text
self . dynamics = [ " f " , " ff " , " p " , " pp " , " mf " , " mp " , " tacet " ]
self . prettyRhythms = [ #list because we need item order
( api . DL , " 0.25 Longa " ) ,
( api . DB , " 0.5 Brevis " ) ,
( api . D1 , " 1 Whole " ) ,
( api . D2 , " 2 Half " ) ,
( api . D4 , " 4 Quarter " ) ,
( api . D8 , " 8 Eigth " ) ,
( api . D16 , " 16 Sixteenth " ) ,
( api . D32 , " 32 Thirthy-Second " ) ,
( api . D64 , " 64 Sixty-Fourth " ) ,
( api . D128 , " 128 Hundred Twenty-Eighth " ) ,
( api . D256 , " 256 Two-hundred Fifty-Sixth " ) ,
]
self . prettyRhythmsStrings = [ v for k , v in self . prettyRhythms ]
self . prettyRhythmsValues = [ k for k , v in self . prettyRhythms ]
self . prettyExtendedRhythms = [ #list because we need item order
( api . DL , " 0.25 Longa " ) ,
( api . DB , " 0.5 Brevis " ) ,
( api . D1 , " 1 Whole " ) ,
( api . D2 , " 2 Half " ) ,
( api . D4 , " 4 Quarter " ) ,
( api . D8 , " 8 Eigth " ) ,
( api . D16 , " 16 Sixteenth " ) ,
( api . D32 , " 32 Thirthy-Second " ) ,
( api . D64 , " 64 Sixty-Fourth " ) ,
( api . D128 , " 128 Hundred Twenty-Eighth " ) ,
( 1.5 * api . DL , " Dotted 0.25 Longa " ) ,
( 1.5 * api . DB , " Dotted 0.5 Brevis " ) ,
( 1.5 * api . D1 , " Dotted 1 Whole " ) ,
( 1.5 * api . D2 , " Dotted 2 Half " ) ,
( 1.5 * api . D4 , " Dotted 4 Quarter " ) ,
( 1.5 * api . D8 , " Dotted 8 Eigth " ) ,
( 1.5 * api . D16 , " Dotted 16 Sixteenth " ) ,
( 1.5 * api . D32 , " Dotted 32 Thirthy-Second " ) ,
( 1.5 * api . D64 , " Dotted 64 Sixty-Fourth " ) ,
( 1.5 * api . D128 , " Dotted 128 Hundred Twenty-Eighth " ) ,
]
self . prettyExtendedRhythmsStrings = [ v for k , v in self . prettyExtendedRhythms ]
self . prettyExtendedRhythmsValues = [ k for k , v in self . prettyExtendedRhythms ]
#use with constantsAndConfigs.musicFont
self . realNoteDisplay = {
api . DB : " 𝅜 " ,
api . D1 : " 𝅝 " ,
api . D2 : " 𝅗𝅥 " ,
api . D4 : " 𝅘𝅥 " ,
api . D8 : " 𝅘𝅥𝅮 " ,
api . D16 : " 𝅘𝅥𝅯 " ,
api . D32 : " 𝅘𝅥𝅰 " ,
api . D64 : " 𝅘𝅥𝅱 " ,
api . D128 : " 𝅘𝅥𝅲 " ,
1.5 * api . DB : " 𝅜𝅭 " , #dotted DB
1.5 * api . D1 : " 𝅝𝅭 " , #dotted D1
1.5 * api . D2 : " 𝅗𝅥𝅭 " , #dotted D2
1.5 * api . D4 : " 𝅘𝅥𝅭 " , #dotted D4
1.5 * api . D8 : " 𝅘𝅥𝅮𝅭 " , #dotted D8
1.5 * api . D16 : " 𝅘𝅥𝅯𝅭 " , #dotted D16
1.5 * api . D32 : " 𝅘𝅥𝅰𝅭 " , #dotted D32
1.5 * api . D64 : " 𝅘𝅥𝅱𝅭 " , #dotted D64
1.5 * api . D128 : " 𝅘𝅥𝅲𝅭 " , #dotted D128
2.25 * api . DB : " 𝅜𝅭 " , #double dotted DB
2.25 * api . D1 : " 𝅝𝅭 " , #double dotted D1
2.25 * api . D2 : " 𝅗𝅥𝅭 " , #double dotted D2
2.25 * api . D4 : " 𝅘𝅥𝅭 " , #double dotted D4
2.25 * api . D8 : " 𝅘𝅥𝅮𝅭 " , #double dotted D8
2.25 * api . D16 : " 𝅘𝅥𝅯𝅭 " , #double dotted D16
2.25 * api . D32 : " 𝅘𝅥𝅰𝅭 " , #double dotted D32
2.25 * api . D64 : " 𝅘𝅥𝅱𝅭 " , #double dotted D64
2.25 * api . D128 : " 𝅘𝅥𝅲𝅭 " , #double dotted D128
}
self . commonNotes = [ #list because we need item order
( api . D1 , " 𝅝 " ) , #D1
( api . D2 , " 𝅗𝅥 " ) , #D2
( api . D4 , " 𝅘𝅥 " ) , #D4
( api . D8 , " 𝅘𝅥𝅮 " ) , #D8
( 1.5 * api . D1 , " 𝅝𝅭 " ) , #dotted D1
( 1.5 * api . D2 , " 𝅗𝅥𝅭 " ) , #dotted D2
( 1.5 * api . D4 , " 𝅘𝅥𝅭 " ) , #dotted D4
( 1.5 * api . D8 , " 𝅘𝅥𝅮𝅭 " ) , #dotted D8
]
self . realNotesStrings = [ v for k , v in self . commonNotes ]
self . realNotesValues = [ k for k , v in self . commonNotes ]
@property
def snapToGrid ( self ) :
return self . _snapToGrid
@snapToGrid . setter
def snapToGrid ( self , value ) :
self . _snapToGrid = value
for func in self . snapToGridCallbacks :
func ( )
constantsAndConfigs = ConstantsAndConfigs ( ) #singleton