فهرست منبع

Improvement/bounding box (#195)

Refactoring (BoundingBox): Removed all manual parent-children connections of boundingBoxes and added auto connections in setParent and the constructor of BoundingBox.
Benjamin Giesinger 7 سال پیش
والد
کامیت
34e5533da2

+ 2 - 0
demo/index.js

@@ -26,6 +26,8 @@ import { OSMD } from '../src/OSMD/OSMD';
             "Dichterliebe01": "Dichterliebe01.xml",
             "mandoline - debussy": "mandoline - debussy.xml",
             "MozartTrio": "MozartTrio.mxl",
+            "Cornelius P. Christbaum Opus 8.1": "Cornelius_P_Christbaum_Opus_8_1_1865.mxl",
+            "France Levasseur - Parlez Mois": "Parlez-moi.mxl",
         },
 
         zoom = 1.0,

+ 18 - 1
src/MusicalScore/Graphical/BoundingBox.ts

@@ -5,6 +5,9 @@ import {RectangleF2D} from "../../Common/DataObjects/RectangleF2D";
 
 /**
  * A bounding box delimits an area on the 2D plane.
+ * @param dataObject Graphical object where the bounding box will be attached
+ * @param parent Parent bounding box of an object in a higher hierarchy position
+ * @param connectChildToParent Create a child to parent relationship too. Will be true by default
  */
 export class BoundingBox {
     protected isSymbol: boolean = false;
@@ -30,12 +33,20 @@ export class BoundingBox {
     protected childElements: BoundingBox[] = [];
     protected parent: BoundingBox;
     protected dataObject: Object;
-
+    /**
+     * Create a bounding box
+     * @param dataObject Graphical object where the bounding box will be attached
+     * @param parent Parent bounding box of an object in a higher hierarchy position
+     * @param connectChildToParent Create a child to parent relationship too. Will be true by default
+     */
     constructor(dataObject: Object = undefined, parent: BoundingBox = undefined) {
         this.parent = parent;
         this.dataObject = dataObject;
         this.xBordersHaveBeenSet = false;
         this.yBordersHaveBeenSet = false;
+        if (parent !== undefined) {
+            this.Parent = parent;
+        }
     }
 
     public get RelativePositionHasBeenSet(): boolean {
@@ -189,6 +200,12 @@ export class BoundingBox {
 
     public set Parent(value: BoundingBox) {
         this.parent = value;
+        if (this.parent.ChildElements.indexOf(this) > -1) {
+            console.error("BoundingBox of " + (this.dataObject.constructor as any).name +
+            " already in children list of " + (this.parent.dataObject.constructor as any).name + "'s BoundingBox");
+        } else {
+            this.parent.ChildElements.push(this);
+        }
     }
 
     public get DataObject(): Object {

+ 0 - 1
src/MusicalScore/Graphical/GraphicalChordSymbolContainer.ts

@@ -25,6 +25,5 @@ export class GraphicalChordSymbolContainer extends GraphicalObject {
         const text: string = ChordSymbolContainer.calculateChordText(this.chordSymbolContainer, transposeHalftones);
         this.graphicalLabel = new GraphicalLabel(new Label(text), textHeight, TextAlignment.CenterBottom, this.boundingBox);
         this.graphicalLabel.PositionAndShape.RelativePosition = new PointF2D(0.0, 0.0);
-        this.boundingBox.ChildElements.push(this.graphicalLabel.PositionAndShape);
     }
 }

+ 2 - 8
src/MusicalScore/Graphical/MusicSheetCalculator.ts

@@ -719,7 +719,6 @@ export abstract class MusicSheetCalculator {
             }
             this.resetYPositionForLeadSheet(graphicalNote.PositionAndShape);
             graphicalStaffEntry.addGraphicalNoteToListAtCorrectYPosition(graphicalNotes, graphicalNote);
-            graphicalStaffEntry.PositionAndShape.ChildElements.push(graphicalNote.PositionAndShape);
             graphicalNote.PositionAndShape.calculateBoundingBox();
             if (!this.leadSheet) {
                 if (note.NoteBeam !== undefined) {
@@ -758,7 +757,6 @@ export abstract class MusicSheetCalculator {
                     graphicalStaffEntry.parentMeasure
                 );
                 graphicalGraceEntries.push(graceStaffEntry);
-                graphicalStaffEntry.PositionAndShape.ChildElements.push(graceStaffEntry.PositionAndShape);
                 this.handleVoiceEntry(
                     graceVoiceEntry, graceStaffEntry, accidentalCalculator, lyricWords,
                     tieTimestampListDict, activeClef, tuplets,
@@ -815,7 +813,6 @@ export abstract class MusicSheetCalculator {
                         const graphicalNotes: GraphicalNote[] =
                             graphicalStaffEntry.findOrCreateGraphicalNotesListFromGraphicalNote(tiedGraphicalNote);
                         graphicalStaffEntry.addGraphicalNoteToListAtCorrectYPosition(graphicalNotes, tiedGraphicalNote);
-                        graphicalStaffEntry.PositionAndShape.ChildElements.push(tiedGraphicalNote.PositionAndShape);
 
                         thisPointer.handleTiedGraphicalNote(tiedGraphicalNote, beams, activeClef, octaveShiftValue, graphicalStaffEntry, tieFraction,
                                                             openTie, isLastTieNote);
@@ -1017,6 +1014,8 @@ export abstract class MusicSheetCalculator {
 
     protected calculatePageLabels(page: GraphicalMusicPage): void {
 
+        // The PositionAndShape child elements of page need to be manually connected to the lyricist, composer, subtitle, etc.
+        // because the page are only available now
         let firstSystemAbsoluteTopMargin: number = 10;
         if (page.MusicSystems.length > 0) {
             const firstMusicSystem: MusicSystem = page.MusicSystems[0];
@@ -1025,7 +1024,6 @@ export abstract class MusicSheetCalculator {
         if (this.graphicalMusicSheet.Title !== undefined) {
             const title: GraphicalLabel = this.graphicalMusicSheet.Title;
             title.PositionAndShape.Parent = page.PositionAndShape;
-            page.PositionAndShape.ChildElements.push(title.PositionAndShape);
             const relative: PointF2D = new PointF2D();
             relative.x = this.graphicalMusicSheet.ParentMusicSheet.pageWidth / 2;
             relative.y = this.rules.TitleTopDistance + this.rules.SheetTitleHeight;
@@ -1035,7 +1033,6 @@ export abstract class MusicSheetCalculator {
         if (this.graphicalMusicSheet.Subtitle !== undefined) {
             const subtitle: GraphicalLabel = this.graphicalMusicSheet.Subtitle;
             subtitle.PositionAndShape.Parent = page.PositionAndShape;
-            page.PositionAndShape.ChildElements.push(subtitle.PositionAndShape);
             const relative: PointF2D = new PointF2D();
             relative.x = this.graphicalMusicSheet.ParentMusicSheet.pageWidth / 2;
             relative.y = this.rules.TitleTopDistance + this.rules.SheetTitleHeight + this.rules.SheetMinimumDistanceBetweenTitleAndSubtitle;
@@ -1045,7 +1042,6 @@ export abstract class MusicSheetCalculator {
         if (this.graphicalMusicSheet.Composer !== undefined) {
             const composer: GraphicalLabel = this.graphicalMusicSheet.Composer;
             composer.PositionAndShape.Parent = page.PositionAndShape;
-            page.PositionAndShape.ChildElements.push(composer.PositionAndShape);
             composer.setLabelPositionAndShapeBorders();
             const relative: PointF2D = new PointF2D();
             relative.x = this.graphicalMusicSheet.ParentMusicSheet.pageWidth - this.rules.PageRightMargin;
@@ -1056,7 +1052,6 @@ export abstract class MusicSheetCalculator {
         if (this.graphicalMusicSheet.Lyricist !== undefined) {
             const lyricist: GraphicalLabel = this.graphicalMusicSheet.Lyricist;
             lyricist.PositionAndShape.Parent = page.PositionAndShape;
-            page.PositionAndShape.ChildElements.push(lyricist.PositionAndShape);
             lyricist.setLabelPositionAndShapeBorders();
             const relative: PointF2D = new PointF2D();
             relative.x = this.rules.PageLeftMargin;
@@ -1327,7 +1322,6 @@ export abstract class MusicSheetCalculator {
                                                                                   new ClefInstruction(),
                                                                                   OctaveEnum.NONE, undefined);
             graphicalNotes.push(graphicalNote);
-            graphicalStaffEntry.PositionAndShape.ChildElements.push(graphicalNote.PositionAndShape);
         }
         return measure;
     }

+ 1 - 3
src/MusicalScore/Graphical/MusicSystem.ts

@@ -119,7 +119,6 @@ export abstract class MusicSystem extends GraphicalObject {
         const leftSystemLine: SystemLine = this.createSystemLine(xPosition, lineWidth, SystemLinesEnum.SingleThin,
                                                                  SystemLinePosition.MeasureBegin, this, top, bottom);
         this.SystemLines.push(leftSystemLine);
-        this.boundingBox.ChildElements.push(leftSystemLine.PositionAndShape);
         leftSystemLine.PositionAndShape.RelativePosition = new PointF2D(xPosition, 0);
         leftSystemLine.PositionAndShape.BorderLeft = 0;
         leftSystemLine.PositionAndShape.BorderRight = lineWidth;
@@ -155,7 +154,6 @@ export abstract class MusicSystem extends GraphicalObject {
             singleVerticalLineAfterMeasure.PositionAndShape.BorderLeft = 0;
             singleVerticalLineAfterMeasure.PositionAndShape.BorderRight = lineWidth;
             this.SystemLines.push(singleVerticalLineAfterMeasure);
-            this.boundingBox.ChildElements.push(singleVerticalLineAfterMeasure.PositionAndShape);
         }
     }
 
@@ -276,7 +274,7 @@ export abstract class MusicSystem extends GraphicalObject {
                 );
                 graphicalLabel.setLabelPositionAndShapeBorders();
                 this.labels.setValue(graphicalLabel, instrument);
-                this.boundingBox.ChildElements.push(graphicalLabel.PositionAndShape);
+                //graphicalLabel.PositionAndShape.Parent = this.PositionAndShape;
 
                 // X-Position will be 0 (Label starts at the same PointF_2D with MusicSystem)
                 // Y-Position will be calculated after the y-Spacing

+ 0 - 5
src/MusicalScore/Graphical/MusicSystemBuilder.ts

@@ -259,8 +259,6 @@ export class MusicSystemBuilder {
     private initMusicSystem(): MusicSystem {
         const musicSystem: MusicSystem = this.symbolFactory.createMusicSystem(this.currentMusicPage, this.globalSystemIndex++);
         this.currentMusicPage.MusicSystems.push(musicSystem);
-        const boundingBox: BoundingBox = musicSystem.PositionAndShape;
-        this.currentMusicPage.PositionAndShape.ChildElements.push(boundingBox);
         return musicSystem;
     }
 
@@ -334,7 +332,6 @@ export class MusicSystemBuilder {
             const staffLine: StaffLine = this.symbolFactory.createStaffLine(musicSystem, staff);
             musicSystem.StaffLines.push(staffLine);
             const boundingBox: BoundingBox = staffLine.PositionAndShape;
-            musicSystem.PositionAndShape.ChildElements.push(boundingBox);
             const relativePosition: PointF2D = new PointF2D();
             if (musicSystem.Parent.MusicSystems[0] === musicSystem && musicSystem.Parent === musicSystem.Parent.Parent.MusicPages[0]) {
                 relativePosition.x = this.rules.FirstSystemMargin;
@@ -631,7 +628,6 @@ export class MusicSystemBuilder {
         measure.PositionAndShape.BorderRight = width;
         currentSystem.StaffLines[visStaffIdx].Measures.push(measure);
         measure.ParentStaffLine = currentSystem.StaffLines[visStaffIdx];
-        currentSystem.StaffLines[visStaffIdx].PositionAndShape.ChildElements.push(measure.PositionAndShape);
         return width;
     }
 
@@ -650,7 +646,6 @@ export class MusicSystemBuilder {
                 const measure: StaffMeasure = gmeasures[visStaffIdx];
                 currentSystem.StaffLines[visStaffIdx].Measures.push(measure);
                 measure.ParentStaffLine = currentSystem.StaffLines[visStaffIdx];
-                currentSystem.StaffLines[visStaffIdx].PositionAndShape.ChildElements.push(measure.PositionAndShape);
             }
             currentSystem.AddStaffMeasures(gmeasures);
         }

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

@@ -81,7 +81,7 @@ export abstract class StaffLine extends GraphicalObject {
         const staffLinePsi: BoundingBox = this.PositionAndShape;
         activitySymbol.PositionAndShape.RelativePosition =
             new PointF2D(staffLinePsi.RelativePosition.x + staffLinePsi.BorderRight + 0.5, staffLinePsi.RelativePosition.y + 0.5);
-        this.parentMusicSystem.PositionAndShape.ChildElements.push(activitySymbol.PositionAndShape);
+        activitySymbol.PositionAndShape.Parent = this.parentMusicSystem.PositionAndShape;
     }
 
     /**

+ 0 - 2
src/MusicalScore/Graphical/StaffMeasure.ts

@@ -279,7 +279,6 @@ export abstract class StaffMeasure extends GraphicalObject {
 
     public addGraphicalStaffEntry(graphicalStaffEntry: GraphicalStaffEntry): void {
         this.staffEntries.push(graphicalStaffEntry);
-        this.PositionAndShape.ChildElements.push(graphicalStaffEntry.PositionAndShape);
     }
 
     /**
@@ -301,7 +300,6 @@ export abstract class StaffMeasure extends GraphicalObject {
                     }
                 }
             }
-            this.PositionAndShape.ChildElements.push(staffEntry.PositionAndShape);
         }
     }
 

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

@@ -184,6 +184,5 @@ export class VexFlowGraphicalSymbolFactory implements IGraphicalSymbolFactory {
       graphicalLabel.setLabelPositionAndShapeBorders();
       graphicalChordSymbolContainer.PositionAndShape.calculateBoundingBox();
       graphicalStaffEntry.graphicalChordContainer = graphicalChordSymbolContainer;
-      graphicalStaffEntry.PositionAndShape.ChildElements.push(graphicalChordSymbolContainer.PositionAndShape);
     }
 }

BIN
test/data/Parlez-moi.mxl