浏览代码

Merge pull request #212 from opensheetmusicdisplay/feature/InstrumentBrace

Added instrument braces and group brackets
Benjamin Giesinger 7 年之前
父节点
当前提交
2f9b5ffcd1

+ 16 - 2
external/vexflow/vexflow.d.ts

@@ -146,6 +146,8 @@ declare namespace Vex {
 
             public getLineForY(y: number): number;
 
+            public getYForLine(y: number): number;
+
             public getModifiers(pos: any, cat: any): Clef[]; // FIXME
             
             public setContext(ctx: RenderContext): Stave;
@@ -263,16 +265,28 @@ declare namespace Vex {
             public attributes: any;
             public state: any;
         }
-
+        
         export class StaveConnector {
             constructor(top: Stave, bottom: Stave);
-
+                        
             public static type: any;
 
             public setType(type: any): StaveConnector;
 
             public setContext(ctx: RenderContext): StaveConnector;
 
+            public setXShift(shift: number): StaveConnector;
+
+            public top_stave: Stave;
+            
+            public bottom_stave: Stave;
+            
+            public thickness: number;
+
+            public width: number;
+
+            public x_shift: number;
+
             public draw(): void;
         }
     }

+ 6 - 2
src/MusicalScore/Graphical/MusicSystem.ts

@@ -247,14 +247,18 @@ export abstract class MusicSystem extends GraphicalObject {
                 continue;
             }
             let firstStaffLine: StaffLine = undefined;
+            let lastStaffLine: StaffLine = undefined;
             for (let idx2: number = 0, len2: number = this.staffLines.length; idx2 < len2; ++idx2) {
                 const staffLine: StaffLine = this.staffLines[idx2];
                 if (staffLine.ParentStaff === instrument1.Staves[0]) {
                     firstStaffLine = staffLine;
                 }
+                if (staffLine.ParentStaff === instrument2.Staves[0]) {
+                    lastStaffLine = staffLine;
+                }
             }
-            if (firstStaffLine !== undefined && firstStaffLine !== undefined) {
-                this.createGroupBracket(firstStaffLine, firstStaffLine, recursionDepth);
+            if (firstStaffLine !== undefined && lastStaffLine !== undefined) {
+                this.createGroupBracket(firstStaffLine, lastStaffLine, recursionDepth);
             }
             if (instrumentGroup.InstrumentalGroups.length < 1) {
                 continue;

+ 1 - 1
src/MusicalScore/Graphical/StaffMeasure.ts

@@ -96,7 +96,7 @@ export abstract class StaffMeasure extends GraphicalObject {
 
     public set ParentStaffLine(value: StaffLine) {
         this.parentStaffLine = value;
-        if (this.parentStaffLine !== undefined) {
+        if (this.parentStaffLine !== undefined && this.PositionAndShape.Parent === undefined) {
             this.PositionAndShape.Parent = this.parentStaffLine.PositionAndShape;
         }
     }

+ 14 - 0
src/MusicalScore/Graphical/VexFlow/VexFlowInstrumentBrace.ts

@@ -0,0 +1,14 @@
+import Vex = require("vexflow");
+import { VexFlowInstrumentBracket } from "./VexFlowInstrumentBracket";
+import { VexFlowStaffLine } from "./VexFlowStaffLine";
+
+/**
+ * Class that defines a instrument bracket at the beginning of a line.
+ */
+export class VexFlowInstrumentBrace extends VexFlowInstrumentBracket {
+
+    constructor(firstVexFlowStaffLine: VexFlowStaffLine, lastVexFlowStaffLine: VexFlowStaffLine, depth: number = 0) {
+        super(firstVexFlowStaffLine, lastVexFlowStaffLine, depth);
+        this.vexflowConnector.setType(Vex.Flow.StaveConnector.type.BRACE);
+    }
+}

+ 20 - 8
src/MusicalScore/Graphical/VexFlow/VexFlowInstrumentBracket.ts

@@ -3,21 +3,21 @@ import {GraphicalObject} from "../GraphicalObject";
 import {VexFlowStaffLine} from "./VexFlowStaffLine";
 import { BoundingBox } from "../BoundingBox";
 import { VexFlowMeasure } from "./VexFlowMeasure";
+import { unitInPixels } from "./VexFlowMusicSheetDrawer";
 
 /**
  * Class that defines a instrument bracket at the beginning of a line.
  */
 export class VexFlowInstrumentBracket extends GraphicalObject {
 
-    private vexflowConnector: Vex.Flow.StaveConnector;
+    protected vexflowConnector: Vex.Flow.StaveConnector;
 
-    constructor(firstVexFlowStaffLine: VexFlowStaffLine, lastVexFlowStaffLine: VexFlowStaffLine) {
+    constructor(firstVexFlowStaffLine: VexFlowStaffLine, lastVexFlowStaffLine: VexFlowStaffLine, depth: number = 0) {
         super();
-        // FIXME: B.Giesinger: Fill in sizes after calculation
-        this.boundingBox = new BoundingBox(this);
+        this.PositionAndShape = new BoundingBox(this, firstVexFlowStaffLine.ParentMusicSystem.PositionAndShape);
         const firstVexMeasure: VexFlowMeasure = firstVexFlowStaffLine.Measures[0] as VexFlowMeasure;
         const lastVexMeasure: VexFlowMeasure = lastVexFlowStaffLine.Measures[0] as VexFlowMeasure;
-        this.addConnector(firstVexMeasure.getVFStave(), lastVexMeasure.getVFStave(), Vex.Flow.StaveConnector.type.BRACE);
+        this.addConnector(firstVexMeasure.getVFStave(), lastVexMeasure.getVFStave(), Vex.Flow.StaveConnector.type.BRACKET, depth);
     }
 
     /**
@@ -25,9 +25,20 @@ export class VexFlowInstrumentBracket extends GraphicalObject {
      * @param ctx Render Vexflow context
      */
     public draw(ctx: Vex.Flow.RenderContext): void {
+        // Draw vexflow brace. This sets the positions inside the connector.
         this.vexflowConnector.setContext(ctx).draw();
+        // Set bounding box
+        const con: Vex.Flow.StaveConnector = this.vexflowConnector;
+        // First line in first stave
+        const topY: number = con.top_stave.getYForLine(0);
+        // Last line in last stave
+        const botY: number = con.bottom_stave.getYForLine(con.bottom_stave.getNumLines() - 1) + con.thickness;
+        // Set bounding box position and size in OSMD units
+        this.PositionAndShape.AbsolutePosition.x = (con.top_stave.getX() - 2 + con.x_shift) / unitInPixels;
+        this.PositionAndShape.AbsolutePosition.y = topY / unitInPixels;
+        this.PositionAndShape.Size.height = (botY - topY) / unitInPixels;
+        this.PositionAndShape.Size.width = 12 / unitInPixels; // width is always 12 -> vexflow implementation
     }
-
     /**
      * Adds a connector between two staves
      *
@@ -35,8 +46,9 @@ export class VexFlowInstrumentBracket extends GraphicalObject {
      * @param {Stave} stave2: Second stave
      * @param {Flow.StaveConnector.type} type: Type of connector
      */
-    private addConnector(stave1: Vex.Flow.Stave, stave2: Vex.Flow.Stave, type: any): void {
+    private addConnector(stave1: Vex.Flow.Stave, stave2: Vex.Flow.Stave, type: any, depth: number): void {
         this.vexflowConnector = new Vex.Flow.StaveConnector(stave1, stave2)
-        .setType(type);
+        .setType(type)
+        .setXShift(depth * -5);
     }
 }

+ 5 - 2
src/MusicalScore/Graphical/VexFlow/VexFlowMusicSheetDrawer.ts

@@ -10,6 +10,7 @@ import {GraphicalLayers} from "../DrawingEnums";
 import {GraphicalStaffEntry} from "../GraphicalStaffEntry";
 import {VexFlowBackend} from "./VexFlowBackend";
 import { VexFlowInstrumentBracket } from "./VexFlowInstrumentBracket";
+import { VexFlowInstrumentBrace } from "./VexFlowInstrumentBrace";
 import { GraphicalLyricEntry } from "../GraphicalLyricEntry";
 
 /**
@@ -109,12 +110,14 @@ export class VexFlowMusicSheetDrawer extends MusicSheetDrawer {
 
     protected drawInstrumentBrace(brace: GraphicalObject, system: MusicSystem): void {
         // Draw InstrumentBrackets at beginning of line
-        const vexBrace: VexFlowInstrumentBracket = (brace as VexFlowInstrumentBracket);
+        const vexBrace: VexFlowInstrumentBrace = (brace as VexFlowInstrumentBrace);
         vexBrace.draw(this.backend.getContext());
     }
 
     protected drawGroupBracket(bracket: GraphicalObject, system: MusicSystem): void {
-        // empty
+        // Draw InstrumentBrackets at beginning of line
+        const vexBrace: VexFlowInstrumentBracket = (bracket as VexFlowInstrumentBracket);
+        vexBrace.draw(this.backend.getContext());
     }
 
     /**

+ 11 - 2
src/MusicalScore/Graphical/VexFlow/VexFlowMusicSystem.ts

@@ -10,6 +10,7 @@ import {VexFlowConverter} from "./VexFlowConverter";
 import {StaffLine} from "../StaffLine";
 import {EngravingRules} from "../EngravingRules";
 import { VexFlowInstrumentBracket } from "./VexFlowInstrumentBracket";
+import { VexFlowInstrumentBrace } from "./VexFlowInstrumentBrace";
 
 export class VexFlowMusicSystem extends MusicSystem {
     constructor(parent: GraphicalMusicPage, id: number) {
@@ -60,7 +61,7 @@ export class VexFlowMusicSystem extends MusicSystem {
         // You could write this in one line but the linter doesn't let me.
         const firstVexStaff: VexFlowStaffLine = (firstStaffLine as VexFlowStaffLine);
         const lastVexStaff: VexFlowStaffLine = (lastStaffLine as VexFlowStaffLine);
-        const vexFlowBracket: VexFlowInstrumentBracket = new VexFlowInstrumentBracket(firstVexStaff, lastVexStaff);
+        const vexFlowBracket: VexFlowInstrumentBrace = new VexFlowInstrumentBrace(firstVexStaff, lastVexStaff);
         this.InstrumentBrackets.push(vexFlowBracket);
         return;
     }
@@ -71,10 +72,18 @@ export class VexFlowMusicSystem extends MusicSystem {
      * The recursion depth informs about the current depth level (needed for positioning)
      * @param firstStaffLine the upper staff line of the bracket to create
      * @param lastStaffLine the lower staff line of the bracket to create
-     * @param staffHeight
      * @param recursionDepth
      */
     protected createGroupBracket(firstStaffLine: StaffLine, lastStaffLine: StaffLine, recursionDepth: number): void {
+        const firstVexStaff: VexFlowStaffLine = (firstStaffLine as VexFlowStaffLine);
+        const lastVexStaff: VexFlowStaffLine = (lastStaffLine as VexFlowStaffLine);
+        if (recursionDepth === 0) {
+            const vexFlowBracket: VexFlowInstrumentBracket = new VexFlowInstrumentBracket(firstVexStaff, lastVexStaff, recursionDepth);
+            this.GroupBrackets.push(vexFlowBracket);
+        } else {
+            const vexFlowBrace: VexFlowInstrumentBrace = new VexFlowInstrumentBrace(firstVexStaff, lastVexStaff, recursionDepth);
+            this.GroupBrackets.push(vexFlowBrace);
+        }
         return;
     }
 }

+ 0 - 1
src/MusicalScore/Graphical/VexFlow/VexFlowStaffLine.ts

@@ -5,6 +5,5 @@ import {Staff} from "../../VoiceData/Staff";
 export class VexFlowStaffLine extends StaffLine {
     constructor(parentSystem: MusicSystem, parentStaff: Staff) {
         super(parentSystem, parentStaff);
-
     }
 }