|
@@ -13,7 +13,6 @@ import {VexFlowStaffEntry} from "./VexFlowStaffEntry";
|
|
import {Beam} from "../../VoiceData/Beam";
|
|
import {Beam} from "../../VoiceData/Beam";
|
|
import {GraphicalNote} from "../GraphicalNote";
|
|
import {GraphicalNote} from "../GraphicalNote";
|
|
import {GraphicalStaffEntry} from "../GraphicalStaffEntry";
|
|
import {GraphicalStaffEntry} from "../GraphicalStaffEntry";
|
|
-import StaveConnector = VF.StaveConnector;
|
|
|
|
import StaveNote = VF.StaveNote;
|
|
import StaveNote = VF.StaveNote;
|
|
import StemmableNote = VF.StemmableNote;
|
|
import StemmableNote = VF.StemmableNote;
|
|
import NoteSubGroup = VF.NoteSubGroup;
|
|
import NoteSubGroup = VF.NoteSubGroup;
|
|
@@ -41,7 +40,7 @@ import { GraphicalTie } from "../GraphicalTie";
|
|
// type StemmableNote = VF.StemmableNote;
|
|
// type StemmableNote = VF.StemmableNote;
|
|
|
|
|
|
export class VexFlowMeasure extends GraphicalMeasure {
|
|
export class VexFlowMeasure extends GraphicalMeasure {
|
|
- constructor(staff: Staff, sourceMeasure: SourceMeasure = undefined, staffLine: StaffLine = undefined) {
|
|
|
|
|
|
+ constructor(staff: Staff, sourceMeasure?: SourceMeasure, staffLine?: StaffLine) {
|
|
super(staff, sourceMeasure, staffLine);
|
|
super(staff, sourceMeasure, staffLine);
|
|
this.minimumStaffEntriesWidth = -1;
|
|
this.minimumStaffEntriesWidth = -1;
|
|
|
|
|
|
@@ -54,6 +53,8 @@ export class VexFlowMeasure extends GraphicalMeasure {
|
|
this.rules = staffLine.ParentMusicSystem.rules;
|
|
this.rules = staffLine.ParentMusicSystem.rules;
|
|
} else if (sourceMeasure) {
|
|
} else if (sourceMeasure) {
|
|
this.rules = sourceMeasure.Rules;
|
|
this.rules = sourceMeasure.Rules;
|
|
|
|
+ } else {
|
|
|
|
+ this.rules = new EngravingRules();
|
|
}
|
|
}
|
|
|
|
|
|
this.resetLayout();
|
|
this.resetLayout();
|
|
@@ -65,23 +66,23 @@ export class VexFlowMeasure extends GraphicalMeasure {
|
|
/** The VexFlow Voices in the measure */
|
|
/** The VexFlow Voices in the measure */
|
|
public vfVoices: { [voiceID: number]: VF.Voice } = {};
|
|
public vfVoices: { [voiceID: number]: VF.Voice } = {};
|
|
/** Call this function (if present) to x-format all the voices in the measure */
|
|
/** Call this function (if present) to x-format all the voices in the measure */
|
|
- public formatVoices: (width: number, parent: VexFlowMeasure) => void;
|
|
|
|
|
|
+ public formatVoices?: (width: number, parent: VexFlowMeasure) => void;
|
|
/** The VexFlow Ties in the measure */
|
|
/** The VexFlow Ties in the measure */
|
|
public vfTies: VF.StaveTie[] = [];
|
|
public vfTies: VF.StaveTie[] = [];
|
|
/** The repetition instructions given as words or symbols (coda, dal segno..) */
|
|
/** The repetition instructions given as words or symbols (coda, dal segno..) */
|
|
public vfRepetitionWords: VF.Repetition[] = [];
|
|
public vfRepetitionWords: VF.Repetition[] = [];
|
|
/** The VexFlow Stave (= one measure in a staffline) */
|
|
/** The VexFlow Stave (= one measure in a staffline) */
|
|
- protected stave: VF.Stave;
|
|
|
|
|
|
+ protected stave!: VF.Stave;
|
|
/** VexFlow StaveConnectors (vertical lines) */
|
|
/** VexFlow StaveConnectors (vertical lines) */
|
|
protected connectors: VF.StaveConnector[] = [];
|
|
protected connectors: VF.StaveConnector[] = [];
|
|
/** Intermediate object to construct beams */
|
|
/** Intermediate object to construct beams */
|
|
- private beams: { [voiceID: number]: [Beam, VexFlowVoiceEntry[]][] } = {};
|
|
|
|
|
|
+ private beams: { [voiceID: number]: [Beam, VexFlowVoiceEntry[]] [] } = {};
|
|
/** Beams created by (optional) autoBeam function. */
|
|
/** Beams created by (optional) autoBeam function. */
|
|
- private autoVfBeams: VF.Beam[];
|
|
|
|
|
|
+ private autoVfBeams: VF.Beam[] = [];
|
|
/** Beams of tuplet notes created by (optional) autoBeam function. */
|
|
/** Beams of tuplet notes created by (optional) autoBeam function. */
|
|
- private autoTupletVfBeams: VF.Beam[];
|
|
|
|
|
|
+ private autoTupletVfBeams: VF.Beam[] = [];
|
|
/** VexFlow Beams */
|
|
/** VexFlow Beams */
|
|
- private vfbeams: { [voiceID: number]: VF.Beam[] };
|
|
|
|
|
|
+ private vfbeams: { [voiceID: number]: VF.Beam[] } = {};
|
|
/** Intermediate object to construct tuplets */
|
|
/** Intermediate object to construct tuplets */
|
|
protected tuplets: { [voiceID: number]: [Tuplet, VexFlowVoiceEntry[]][] } = {};
|
|
protected tuplets: { [voiceID: number]: [Tuplet, VexFlowVoiceEntry[]][] } = {};
|
|
/** VexFlow Tuplets */
|
|
/** VexFlow Tuplets */
|
|
@@ -187,14 +188,14 @@ export class VexFlowMeasure extends GraphicalMeasure {
|
|
public setLineNumber(lineNumber: number): void {
|
|
public setLineNumber(lineNumber: number): void {
|
|
if (lineNumber !== 5) {
|
|
if (lineNumber !== 5) {
|
|
if (lineNumber === 0) {
|
|
if (lineNumber === 0) {
|
|
- (this.stave as any).setNumLines(0);
|
|
|
|
|
|
+ this.stave.setNumLines(0);
|
|
this.stave.getBottomLineY = function(): number {
|
|
this.stave.getBottomLineY = function(): number {
|
|
return this.getYForLine(this.options.num_lines);
|
|
return this.getYForLine(this.options.num_lines);
|
|
};
|
|
};
|
|
} else if (lineNumber === 1) {
|
|
} else if (lineNumber === 1) {
|
|
// VF.Stave.setNumLines hides all but the top line.
|
|
// VF.Stave.setNumLines hides all but the top line.
|
|
// this is better
|
|
// this is better
|
|
- (this.stave.options as any).line_config = [
|
|
|
|
|
|
+ this.stave.options.line_config = [
|
|
{ visible: false },
|
|
{ visible: false },
|
|
{ visible: false },
|
|
{ visible: false },
|
|
{ visible: true }, // show middle
|
|
{ visible: true }, // show middle
|
|
@@ -208,7 +209,7 @@ export class VexFlowMeasure extends GraphicalMeasure {
|
|
//lines (which isn't this case here)
|
|
//lines (which isn't this case here)
|
|
//this.stave.options.num_lines = parseInt(lines, 10);
|
|
//this.stave.options.num_lines = parseInt(lines, 10);
|
|
} else if (lineNumber === 2) {
|
|
} else if (lineNumber === 2) {
|
|
- (this.stave.options as any).line_config = [
|
|
|
|
|
|
+ this.stave.options.line_config = [
|
|
{ visible: false },
|
|
{ visible: false },
|
|
{ visible: false },
|
|
{ visible: false },
|
|
{ visible: true }, // show middle
|
|
{ visible: true }, // show middle
|
|
@@ -219,7 +220,7 @@ export class VexFlowMeasure extends GraphicalMeasure {
|
|
return this.getYForLine(3);
|
|
return this.getYForLine(3);
|
|
};
|
|
};
|
|
} else if (lineNumber === 3) {
|
|
} else if (lineNumber === 3) {
|
|
- (this.stave.options as any).line_config = [
|
|
|
|
|
|
+ this.stave.options.line_config = [
|
|
{ visible: false },
|
|
{ visible: false },
|
|
{ visible: true },
|
|
{ visible: true },
|
|
{ visible: true }, // show middle
|
|
{ visible: true }, // show middle
|
|
@@ -230,7 +231,7 @@ export class VexFlowMeasure extends GraphicalMeasure {
|
|
return this.getYForLine(2);
|
|
return this.getYForLine(2);
|
|
};
|
|
};
|
|
} else {
|
|
} else {
|
|
- (this.stave as any).setNumLines(lineNumber);
|
|
|
|
|
|
+ this.stave.setNumLines(lineNumber);
|
|
this.stave.getBottomLineY = function(): number {
|
|
this.stave.getBottomLineY = function(): number {
|
|
return this.getYForLine(this.options.num_lines);
|
|
return this.getYForLine(this.options.num_lines);
|
|
};
|
|
};
|
|
@@ -270,7 +271,7 @@ export class VexFlowMeasure extends GraphicalMeasure {
|
|
);
|
|
);
|
|
if (!this.ShowTimeSignature) {
|
|
if (!this.ShowTimeSignature) {
|
|
// extends Element is missing from class StaveModifier in DefinitelyTyped definitions, so setStyle isn't found
|
|
// extends Element is missing from class StaveModifier in DefinitelyTyped definitions, so setStyle isn't found
|
|
- (timeSig as any).setStyle({ fillStyle: "#00000000"}); // transparent. requires VexflowPatch
|
|
|
|
|
|
+ timeSig.setStyle({ fillStyle: "#00000000"}); // transparent. requires VexflowPatch
|
|
}
|
|
}
|
|
this.updateInstructionWidth();
|
|
this.updateInstructionWidth();
|
|
}
|
|
}
|
|
@@ -282,7 +283,7 @@ export class VexFlowMeasure extends GraphicalMeasure {
|
|
*/
|
|
*/
|
|
public addClefAtEnd(clef: ClefInstruction, visible: boolean = true): void {
|
|
public addClefAtEnd(clef: ClefInstruction, visible: boolean = true): void {
|
|
const vfclef: { type: string, size: string, annotation: string } = VexFlowConverter.Clef(clef, "small");
|
|
const vfclef: { type: string, size: string, annotation: string } = VexFlowConverter.Clef(clef, "small");
|
|
- if (!visible && (this.stave as any).endClef) {
|
|
|
|
|
|
+ if (!visible && this.stave.endClef) {
|
|
return; // don't overwrite existing clef with invisible clef
|
|
return; // don't overwrite existing clef with invisible clef
|
|
}
|
|
}
|
|
this.stave.setEndClef(vfclef.type, vfclef.size, vfclef.annotation);
|
|
this.stave.setEndClef(vfclef.type, vfclef.size, vfclef.annotation);
|
|
@@ -292,25 +293,25 @@ export class VexFlowMeasure extends GraphicalMeasure {
|
|
if (modifier.getCategory() === "clefs" && modifier.getPosition() === VF.StaveModifier.Position.END) {
|
|
if (modifier.getCategory() === "clefs" && modifier.getPosition() === VF.StaveModifier.Position.END) {
|
|
if ((modifier as any).type === vfclef.type) { // any = VF.Clef
|
|
if ((modifier as any).type === vfclef.type) { // any = VF.Clef
|
|
const transparentStyle: string = "#12345600";
|
|
const transparentStyle: string = "#12345600";
|
|
- const originalStyle: any = (modifier as any).getStyle();
|
|
|
|
|
|
+ const originalStyle: any = modifier.getStyle();
|
|
if (originalStyle) {
|
|
if (originalStyle) {
|
|
(modifier as any).originalStrokeStyle = originalStyle.strokeStyle;
|
|
(modifier as any).originalStrokeStyle = originalStyle.strokeStyle;
|
|
(modifier as any).originalFillStyle = originalStyle.fillStyle;
|
|
(modifier as any).originalFillStyle = originalStyle.fillStyle;
|
|
}
|
|
}
|
|
- (modifier as any).setStyle({strokeStyle: transparentStyle, fillStyle: transparentStyle});
|
|
|
|
|
|
+ modifier.setStyle({strokeStyle: transparentStyle, fillStyle: transparentStyle});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
// reset invisible style
|
|
// reset invisible style
|
|
const originalStrokeStyle: any = (modifier as any).originalStrokeStyle;
|
|
const originalStrokeStyle: any = (modifier as any).originalStrokeStyle;
|
|
const originalFillStyle: any = (modifier as any).originalFillStyle;
|
|
const originalFillStyle: any = (modifier as any).originalFillStyle;
|
|
- if ((modifier as any).getStyle()) {
|
|
|
|
|
|
+ if (modifier.getStyle()) {
|
|
if (originalStrokeStyle && originalFillStyle) {
|
|
if (originalStrokeStyle && originalFillStyle) {
|
|
- ((modifier as any).getStyle() as any).strokeStyle = originalStrokeStyle;
|
|
|
|
- ((modifier as any).getStyle() as any).fillStyle = originalFillStyle;
|
|
|
|
|
|
+ modifier.getStyle().strokeStyle = originalStrokeStyle;
|
|
|
|
+ modifier.getStyle().fillStyle = originalFillStyle;
|
|
} else {
|
|
} else {
|
|
- ((modifier as any).getStyle() as any).strokeStyle = null;
|
|
|
|
- ((modifier as any).getStyle() as any).fillStyle = null;
|
|
|
|
|
|
+ modifier.getStyle().strokeStyle = null;
|
|
|
|
+ modifier.getStyle().fillStyle = null;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -400,18 +401,16 @@ export class VexFlowMeasure extends GraphicalMeasure {
|
|
public addMeasureNumber(): void {
|
|
public addMeasureNumber(): void {
|
|
const text: string = this.MeasureNumber.toString();
|
|
const text: string = this.MeasureNumber.toString();
|
|
const position: number = StavePositionEnum.ABOVE; //VF.StaveModifier.Position.ABOVE;
|
|
const position: number = StavePositionEnum.ABOVE; //VF.StaveModifier.Position.ABOVE;
|
|
- const options: any = {
|
|
|
|
|
|
+ this.stave.setText(text, position, {
|
|
justification: 1,
|
|
justification: 1,
|
|
shift_x: 0,
|
|
shift_x: 0,
|
|
shift_y: 0,
|
|
shift_y: 0,
|
|
- };
|
|
|
|
-
|
|
|
|
- this.stave.setText(text, position, options);
|
|
|
|
|
|
+ });
|
|
}
|
|
}
|
|
|
|
|
|
public addWordRepetition(repetitionInstruction: RepetitionInstruction): void {
|
|
public addWordRepetition(repetitionInstruction: RepetitionInstruction): void {
|
|
- let instruction: VF.Repetition.type = undefined;
|
|
|
|
- let position: any = VF.StaveModifier.Position.END;
|
|
|
|
|
|
+ let instruction: number | undefined;
|
|
|
|
+ let position: number = VF.StaveModifier.Position.END;
|
|
const xShift: number = this.beginInstructionsWidth;
|
|
const xShift: number = this.beginInstructionsWidth;
|
|
switch (repetitionInstruction.type) {
|
|
switch (repetitionInstruction.type) {
|
|
case RepetitionInstructionEnum.Segno:
|
|
case RepetitionInstructionEnum.Segno:
|
|
@@ -694,7 +693,7 @@ export class VexFlowMeasure extends GraphicalMeasure {
|
|
} else {
|
|
} else {
|
|
relPosY += 0.5; // center-align bbox
|
|
relPosY += 0.5; // center-align bbox
|
|
}
|
|
}
|
|
- const line: any = -gNote.notehead(vfnote).line; // vexflow y direction is opposite of osmd's
|
|
|
|
|
|
+ const line: number = -gNote.notehead(vfnote).line; // vexflow y direction is opposite of osmd's
|
|
relPosY += line + (gNote.parentVoiceEntry.notes.last() as VexFlowGraphicalNote).notehead().line; // don't move for first note: - (-vexline)
|
|
relPosY += line + (gNote.parentVoiceEntry.notes.last() as VexFlowGraphicalNote).notehead().line; // don't move for first note: - (-vexline)
|
|
gNote.PositionAndShape.RelativePosition.y = relPosY;
|
|
gNote.PositionAndShape.RelativePosition.y = relPosY;
|
|
}
|
|
}
|
|
@@ -742,7 +741,7 @@ export class VexFlowMeasure extends GraphicalMeasure {
|
|
* @param voice the voice for which the ghost notes shall be searched.
|
|
* @param voice the voice for which the ghost notes shall be searched.
|
|
*/
|
|
*/
|
|
protected getRestFilledVexFlowStaveNotesPerVoice(voice: Voice): GraphicalVoiceEntry[] {
|
|
protected getRestFilledVexFlowStaveNotesPerVoice(voice: Voice): GraphicalVoiceEntry[] {
|
|
- let latestVoiceTimestamp: Fraction = undefined;
|
|
|
|
|
|
+ let latestVoiceTimestamp: Fraction;
|
|
let gvEntries: GraphicalVoiceEntry[] = this.getGraphicalVoiceEntriesPerVoice(voice);
|
|
let gvEntries: GraphicalVoiceEntry[] = this.getGraphicalVoiceEntriesPerVoice(voice);
|
|
for (let idx: number = 0; idx < gvEntries.length; idx++) {
|
|
for (let idx: number = 0; idx < gvEntries.length; idx++) {
|
|
const gve: GraphicalVoiceEntry = gvEntries[idx];
|
|
const gve: GraphicalVoiceEntry = gvEntries[idx];
|
|
@@ -908,7 +907,7 @@ export class VexFlowMeasure extends GraphicalMeasure {
|
|
let beamColor: string;
|
|
let beamColor: string;
|
|
const stemColors: string[] = [];
|
|
const stemColors: string[] = [];
|
|
for (const entry of voiceEntries) {
|
|
for (const entry of voiceEntries) {
|
|
- const note: VF.StaveNote = ((<VexFlowVoiceEntry>entry).vfStaveNote as StaveNote);
|
|
|
|
|
|
+ const note: VF.StaveNote = entry.vfStaveNote as StaveNote;
|
|
if (note) {
|
|
if (note) {
|
|
notes.push(note);
|
|
notes.push(note);
|
|
beamedNotes.push(note);
|
|
beamedNotes.push(note);
|
|
@@ -1113,7 +1112,7 @@ export class VexFlowMeasure extends GraphicalMeasure {
|
|
* Complete the creation of VexFlow Tuplets in this measure
|
|
* Complete the creation of VexFlow Tuplets in this measure
|
|
*/
|
|
*/
|
|
public finalizeTuplets(): void {
|
|
public finalizeTuplets(): void {
|
|
- // The following line resets the created Vex.Flow Tuplets and
|
|
|
|
|
|
+ // The following line resets the created VF Tuplets and
|
|
// created them brand new. Is this needed? And more importantly,
|
|
// created them brand new. Is this needed? And more importantly,
|
|
// should the old tuplets be removed manually from the notes?
|
|
// should the old tuplets be removed manually from the notes?
|
|
this.vftuplets = {};
|
|
this.vftuplets = {};
|
|
@@ -1257,7 +1256,7 @@ export class VexFlowMeasure extends GraphicalMeasure {
|
|
}
|
|
}
|
|
|
|
|
|
const vexFlowVoiceEntry: VexFlowVoiceEntry = voiceEntry as VexFlowVoiceEntry;
|
|
const vexFlowVoiceEntry: VexFlowVoiceEntry = voiceEntry as VexFlowVoiceEntry;
|
|
- if ((vexFlowVoiceEntry.vfStaveNote as any).ticks.denominator === 0) {
|
|
|
|
|
|
+ if (vexFlowVoiceEntry.vfStaveNote.getTicks().denominator === 0) {
|
|
continue; // TODO not sure why the ticks aren't calculated correctly, see #1073
|
|
continue; // TODO not sure why the ticks aren't calculated correctly, see #1073
|
|
// if denominator === 0, addTickable() below goes into an infinite loop.
|
|
// if denominator === 0, addTickable() below goes into an infinite loop.
|
|
}
|
|
}
|
|
@@ -1472,7 +1471,7 @@ export class VexFlowMeasure extends GraphicalMeasure {
|
|
fretFinger.setOffsetY(offsetYSign * (ordering + shiftCount) * perFingeringShift);
|
|
fretFinger.setOffsetY(offsetYSign * (ordering + shiftCount) * perFingeringShift);
|
|
} else if (!this.rules.FingeringInsideStafflines) { // use StringNumber for placement above/below stafflines
|
|
} else if (!this.rules.FingeringInsideStafflines) { // use StringNumber for placement above/below stafflines
|
|
const stringNumber: VF.StringNumber = new VF.StringNumber(fingering.value);
|
|
const stringNumber: VF.StringNumber = new VF.StringNumber(fingering.value);
|
|
- (<any>stringNumber).radius = 0; // hack to remove the circle around the number
|
|
|
|
|
|
+ stringNumber.radius = 0; // hack to remove the circle around the number
|
|
stringNumber.setPosition(modifierPosition);
|
|
stringNumber.setPosition(modifierPosition);
|
|
stringNumber.setOffsetY(offsetYSign * ordering * stringNumber.getWidth() * 2 / 3);
|
|
stringNumber.setOffsetY(offsetYSign * ordering * stringNumber.getWidth() * 2 / 3);
|
|
// Vexflow made a mess with the addModifier signature that changes through each class so we just cast to any :(
|
|
// Vexflow made a mess with the addModifier signature that changes through each class so we just cast to any :(
|
|
@@ -1525,7 +1524,7 @@ export class VexFlowMeasure extends GraphicalMeasure {
|
|
// Remove circle from string number. Not needed for
|
|
// Remove circle from string number. Not needed for
|
|
// disambiguation from fingerings since we use Roman
|
|
// disambiguation from fingerings since we use Roman
|
|
// Numerals for RenderStringNumbersClassical
|
|
// Numerals for RenderStringNumbersClassical
|
|
- (<any>vfStringNumber).radius = 0;
|
|
|
|
|
|
+ vfStringNumber.radius = 0;
|
|
const offsetY: number = -this.rules.StringNumberOffsetY;
|
|
const offsetY: number = -this.rules.StringNumberOffsetY;
|
|
// if (note.sourceNote.halfTone < 50) { // place string number a little higher for notes with ledger lines below staff
|
|
// if (note.sourceNote.halfTone < 50) { // place string number a little higher for notes with ledger lines below staff
|
|
// // TODO also check for treble clef (adjust for viola, cello, etc)
|
|
// // TODO also check for treble clef (adjust for viola, cello, etc)
|
|
@@ -1550,7 +1549,7 @@ export class VexFlowMeasure extends GraphicalMeasure {
|
|
* @param lineType
|
|
* @param lineType
|
|
*/
|
|
*/
|
|
public lineTo(top: VexFlowMeasure, lineType: any): void {
|
|
public lineTo(top: VexFlowMeasure, lineType: any): void {
|
|
- const connector: StaveConnector = new VF.StaveConnector(top.getVFStave(), this.stave);
|
|
|
|
|
|
+ const connector: VF.StaveConnector = new VF.StaveConnector(top.getVFStave(), this.stave);
|
|
connector.setType(lineType);
|
|
connector.setType(lineType);
|
|
this.connectors.push(connector);
|
|
this.connectors.push(connector);
|
|
}
|
|
}
|