src/MusicalScore/Graphical/GraphicalNote.ts
import {Note} from "../VoiceData/Note";
import {Fraction} from "../../Common/DataObjects/Fraction";
import {KeyInstruction} from "../VoiceData/Instructions/KeyInstruction";
import {ClefInstruction} from "../VoiceData/Instructions/ClefInstruction";
import {OctaveEnum} from "../VoiceData/Expressions/ContinuousExpressions/OctaveShift";
import {AccidentalEnum, Pitch} from "../../Common/DataObjects/Pitch";
import {GraphicalObject} from "./GraphicalObject";
import {MusicSheetCalculator} from "./MusicSheetCalculator";
import {BoundingBox} from "./BoundingBox";
import {GraphicalVoiceEntry} from "./GraphicalVoiceEntry";
import {GraphicalMusicPage} from "./GraphicalMusicPage";
import { EngravingRules } from "./EngravingRules";
/**
* The graphical counterpart of a [[Note]]
*/
export class GraphicalNote extends GraphicalObject {
constructor(note: Note, parent: GraphicalVoiceEntry, rules: EngravingRules, graphicalNoteLength: Fraction = undefined) {
super();
this.sourceNote = note;
this.parentVoiceEntry = parent;
this.PositionAndShape = new BoundingBox(this, parent.PositionAndShape);
if (graphicalNoteLength) {
this.graphicalNoteLength = graphicalNoteLength;
} else {
this.graphicalNoteLength = note.Length;
}
this.numberOfDots = this.calculateNumberOfNeededDots(this.graphicalNoteLength);
this.rules = rules;
this.rules.addGraphicalNoteToNoteMap(note, this);
}
public sourceNote: Note;
public DrawnAccidental: AccidentalEnum = AccidentalEnum.NONE;
public graphicalNoteLength: Fraction;
public parentVoiceEntry: GraphicalVoiceEntry;
public numberOfDots: number;
public rules: EngravingRules;
public staffLine: number;
public baseFingeringXOffset: number;
public baseStringNumberXOffset: number;
public lineShift: number = 0;
public Transpose(keyInstruction: KeyInstruction, activeClef: ClefInstruction, halfTones: number, octaveEnum: OctaveEnum): Pitch {
let transposedPitch: Pitch = this.sourceNote.Pitch;
if (MusicSheetCalculator.transposeCalculator) {
transposedPitch = MusicSheetCalculator.transposeCalculator.transposePitch(this.sourceNote.Pitch, keyInstruction, halfTones);
}
return transposedPitch;
}
/**
* Return the number of dots needed to represent the given fraction.
* @param fraction
* @returns {number}
*/
private calculateNumberOfNeededDots(fraction: Fraction): number {
if (!this.sourceNote || !this.sourceNote.NoteTuplet) {
return fraction.calculateNumberOfNeededDots();
}
return 0;
}
public get ParentMusicPage(): GraphicalMusicPage {
return this.parentVoiceEntry.parentStaffEntry.parentMeasure.ParentMusicSystem.Parent;
}
/** Get a GraphicalNote from a Note. Use osmd.rules as the second parameter (instance reference).
* Also more easily available via osmd.rules.GNote(note). */
public static FromNote(note: Note, rules: EngravingRules): GraphicalNote {
return rules.NoteToGraphicalNoteMap.getValue(note.NoteToGraphicalNoteObjectId);
}
public ToStringShort(octaveOffset: number = 0): string {
return this.sourceNote?.ToStringShort(octaveOffset);
}
public get ToStringShortGet(): string {
return this.ToStringShort(0);
}
}