|
|
|
#! /usr/bin/env python3
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
"""
|
|
|
|
Copyright 2020, Nils Hilbricht, Germany ( https://www.hilbricht.net )
|
|
|
|
|
|
|
|
This file is part of the Laborejo Software Suite ( https://www.laborejo.org ),
|
|
|
|
|
|
|
|
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; logger = logging.getLogger(__name__); logger.info("import")
|
|
|
|
|
|
|
|
|
|
|
|
#Third Party Modules
|
|
|
|
from PyQt5 import QtWidgets, QtCore, QtGui
|
|
|
|
|
|
|
|
#Template Modules
|
|
|
|
from .resources import *
|
|
|
|
|
|
|
|
#Client Modules
|
|
|
|
import engine.api as api
|
|
|
|
|
|
|
|
|
|
|
|
class ConstantsAndConfigs(object):
|
|
|
|
"""Handles shared widgets like the Grid and ScoreView with Zoom and Stretch"""
|
|
|
|
|
|
|
|
def __init__(self):
|
|
|
|
self.ticksToPixelRatio = None #Must be set by the client ConstantsAndConfigs!
|
|
|
|
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.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._snapToGrid = True # For CC point and Tempo point placements
|
|
|
|
self.snapToGridCallbacks = [] # see ccViewCallbacks
|
|
|
|
|
|
|
|
self.zoomFactor = 1 # #Initial Zoom Level. Also hardcoded into scoreView.zoomNull. Lower means bigger items.
|
|
|
|
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(":template/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()
|