Browse Source

feat: implemented showing in-measure clefs

Matthias Uiberacker 7 years ago
parent
commit
3158eb47bc

+ 5 - 1
external/vexflow/vexflow.d.ts

@@ -225,7 +225,7 @@ declare namespace Vex {
         }
 
         export class Clef extends StaveModifier {
-            constructor(type: string, size: number, annotation: string);
+            constructor(type: string, size: string, annotation: string);
 
             public static category: string;
             public static types: { [type: string]: any; };
@@ -237,6 +237,10 @@ declare namespace Vex {
 
             public setStave(stave: Stave): void;
         }
+        
+        export class ClefNote  extends Note {
+            constructor(type: string, size: string, annotation: string);
+        }
 
         export class Renderer {
             constructor(canvas: HTMLElement, backend: number);

+ 5 - 0
src/MusicalScore/Graphical/VexFlow/VexFlowGraphicalSymbolFactory.ts

@@ -1,3 +1,4 @@
+import Vex = require("vexflow");
 import {IGraphicalSymbolFactory} from "../../Interfaces/IGraphicalSymbolFactory";
 import {GraphicalMusicPage} from "../GraphicalMusicPage";
 import {MusicSystem} from "../MusicSystem";
@@ -25,6 +26,7 @@ import { TechnicalInstruction } from "../../VoiceData/Instructions/TechnicalInst
 import { GraphicalVoiceEntry } from "../GraphicalVoiceEntry";
 import { VoiceEntry } from "../../VoiceData/VoiceEntry";
 import { VexFlowVoiceEntry } from "./VexFlowVoiceEntry";
+import { VexFlowConverter } from "./VexFlowConverter";
 
 export class VexFlowGraphicalSymbolFactory implements IGraphicalSymbolFactory {
     /**
@@ -141,6 +143,9 @@ export class VexFlowGraphicalSymbolFactory implements IGraphicalSymbolFactory {
      * @param clefInstruction
      */
     public createInStaffClef(graphicalStaffEntry: GraphicalStaffEntry, clefInstruction: ClefInstruction): void {
+        const se: VexFlowStaffEntry = graphicalStaffEntry as VexFlowStaffEntry;
+        const vfClefParams: { type: string, size: string, annotation: string } = VexFlowConverter.Clef(clefInstruction, "small");
+        se.vfClefBefore = new Vex.Flow.ClefNote(vfClefParams.type, vfClefParams.size, vfClefParams.annotation);
         return;
     }
 

+ 19 - 3
src/MusicalScore/Graphical/VexFlow/VexFlowMeasure.ts

@@ -25,6 +25,7 @@ import {GraphicalVoiceEntry} from "../GraphicalVoiceEntry";
 import {VexFlowVoiceEntry} from "./VexFlowVoiceEntry";
 import {Fraction} from "../../../Common/DataObjects/Fraction";
 import { Voice } from "../../VoiceData/Voice";
+import { LinkedVoice } from "../../VoiceData/LinkedVoice";
 
 export class VexFlowMeasure extends GraphicalMeasure {
     constructor(staff: Staff, staffLine: StaffLine = undefined, sourceMeasure: SourceMeasure = undefined) {
@@ -451,6 +452,8 @@ export class VexFlowMeasure extends GraphicalMeasure {
 
             // finally set the latest timestamp of this voice to the end timestamp of the longest note in the current voiceEntry:
             latestVoiceTimestamp = gNotesEndTimestamp;
+
+
         }
 
         const measureEndTimestamp: Fraction = Fraction.plus(this.parentSourceMeasure.AbsoluteTimestamp, this.parentSourceMeasure.Duration);
@@ -636,6 +639,8 @@ export class VexFlowMeasure extends GraphicalMeasure {
         const voices: Voice[] = this.getVoicesWithinMeasure();
 
         for (const voice of voices) {
+            const isMainVoice: boolean = !(voice instanceof LinkedVoice);
+
             // add a vexFlow voice for this voice:
             this.vfVoices[voice.VoiceId] = new Vex.Flow.Voice({
                             beat_value: this.parentSourceMeasure.Duration.Denominator,
@@ -645,16 +650,27 @@ export class VexFlowMeasure extends GraphicalMeasure {
 
             const restFilledEntries: GraphicalVoiceEntry[] =  this.getRestFilledVexFlowStaveNotesPerVoice(voice);
             // create vex flow voices and add tickables to it:
-            //let graceGVoiceEntriesBefore: GraphicalVoiceEntry[] = [];
+            // let graceGVoiceEntriesBefore: GraphicalVoiceEntry[] = [];
             for (const voiceEntry of restFilledEntries) {
                 if (!voiceEntry.parentVoiceEntry) {
                     continue;
                 }
                 if (voiceEntry.parentVoiceEntry.IsGrace) {
                     continue;
+                }
+                const vexFlowVoiceEntry: VexFlowVoiceEntry = voiceEntry as VexFlowVoiceEntry;
+
+                // check for in-measure clefs:
+                // only add clefs in main voice (to not add them twice)
+                if (isMainVoice) {
+                    const vfse: VexFlowStaffEntry = vexFlowVoiceEntry.parentStaffEntry as VexFlowStaffEntry;
+                    if (vfse.vfClefBefore !== undefined) {
+                        // add the clef as Vex.Flow.ClefNote
+                        this.vfVoices[voice.VoiceId].addTickable(vfse.vfClefBefore);
+                    }
+                }
+                this.vfVoices[voice.VoiceId].addTickable(vexFlowVoiceEntry.vfStaveNote);
             }
-                this.vfVoices[voice.VoiceId].addTickable((voiceEntry as VexFlowVoiceEntry).vfStaveNote);
-        }
         }
         this.createArticulations();
         this.createOrnaments();

+ 4 - 0
src/MusicalScore/Graphical/VexFlow/VexFlowStaffEntry.ts

@@ -9,6 +9,10 @@ export class VexFlowStaffEntry extends GraphicalStaffEntry {
         super(measure, sourceStaffEntry, staffEntryParent);
     }
 
+    // if there is a in-measure clef given before this staffEntry,
+    // it will be converted to a Vex.Flow.ClefNote and assigned to this variable:
+    public vfClefBefore: Vex.Flow.ClefNote;
+
     /**
      * Calculates the staff entry positions from the VexFlow stave information and the tickabels inside the staff.
      * This is needed in order to set the OSMD staff entries (which are almost the same as tickables) to the correct positionts.