瀏覽代碼

fix(Cursor): starts and ends at selected range of measures to draw (#566)

when you set drawFromMeasureNumber or drawUpToMeasureNumber, re-render,
and show the cursor, it correctly sets its iterator now, so it stays within render range

fix #566
sschmid 5 年之前
父節點
當前提交
3fe770efcf
共有 1 個文件被更改,包括 32 次插入5 次删除
  1. 32 5
      src/OpenSheetMusicDisplay/Cursor.ts

+ 32 - 5
src/OpenSheetMusicDisplay/Cursor.ts

@@ -7,6 +7,8 @@ import {OpenSheetMusicDisplay} from "./OpenSheetMusicDisplay";
 import {GraphicalMusicSheet} from "../MusicalScore/Graphical/GraphicalMusicSheet";
 import {GraphicalMusicSheet} from "../MusicalScore/Graphical/GraphicalMusicSheet";
 import {Instrument} from "../MusicalScore/Instrument";
 import {Instrument} from "../MusicalScore/Instrument";
 import {Note} from "../MusicalScore/VoiceData/Note";
 import {Note} from "../MusicalScore/VoiceData/Note";
+import {EngravingRules, Fraction} from "..";
+import {SourceMeasure} from "../MusicalScore";
 
 
 /**
 /**
  * A cursor which can iterate through the music sheet.
  * A cursor which can iterate through the music sheet.
@@ -44,9 +46,34 @@ export class Cursor {
    */
    */
   public show(): void {
   public show(): void {
     this.hidden = false;
     this.hidden = false;
+    this.resetIterator(); // TODO maybe not here? though setting measure range to draw, rerendering, then handling cursor show is difficult
     this.update();
     this.update();
   }
   }
 
 
+  public resetIterator(): void {
+    if (!this.openSheetMusicDisplay.Sheet || !this.openSheetMusicDisplay.Sheet.SourceMeasures) { // just a safety measure
+      console.log("OSMD.Cursor.resetIterator(): sheet or measures were null/undefined.");
+      return;
+    }
+
+    // set selection start, so that when there's MinMeasureToDraw set, the cursor starts there right away instead of at measure 1
+    const lastSheetMeasureIndex: number = this.openSheetMusicDisplay.Sheet.SourceMeasures.length - 1; // last measure in data model
+    let startMeasureIndex: number = EngravingRules.Rules.MinMeasureToDrawIndex;
+    startMeasureIndex = Math.min(startMeasureIndex, lastSheetMeasureIndex);
+    let endMeasureIndex: number = EngravingRules.Rules.MaxMeasureToDrawIndex;
+    endMeasureIndex = Math.min(endMeasureIndex, lastSheetMeasureIndex);
+
+    if (this.openSheetMusicDisplay.Sheet && this.openSheetMusicDisplay.Sheet.SourceMeasures.length > startMeasureIndex) {
+      this.openSheetMusicDisplay.Sheet.SelectionStart = this.openSheetMusicDisplay.Sheet.SourceMeasures[startMeasureIndex].AbsoluteTimestamp;
+    }
+    if (this.openSheetMusicDisplay.Sheet && this.openSheetMusicDisplay.Sheet.SourceMeasures.length > endMeasureIndex) {
+      const lastMeasure: SourceMeasure = this.openSheetMusicDisplay.Sheet.SourceMeasures[endMeasureIndex];
+      this.openSheetMusicDisplay.Sheet.SelectionEnd = Fraction.plus(lastMeasure.AbsoluteTimestamp, lastMeasure.Duration);
+    }
+
+    this.iterator = this.manager.getIterator();
+  }
+
   private getStaffEntriesFromVoiceEntry(voiceEntry: VoiceEntry): VexFlowStaffEntry {
   private getStaffEntriesFromVoiceEntry(voiceEntry: VoiceEntry): VexFlowStaffEntry {
     const measureIndex: number = voiceEntry.ParentSourceStaffEntry.VerticalContainerParent.ParentMeasure.measureListIndex;
     const measureIndex: number = voiceEntry.ParentSourceStaffEntry.VerticalContainerParent.ParentMeasure.measureListIndex;
     const staffIndex: number = voiceEntry.ParentSourceStaffEntry.ParentStaff.idInMusicSheet;
     const staffIndex: number = voiceEntry.ParentSourceStaffEntry.ParentStaff.idInMusicSheet;
@@ -60,6 +87,8 @@ export class Cursor {
     }
     }
     this.graphic.Cursors.length = 0;
     this.graphic.Cursors.length = 0;
     const iterator: MusicPartManagerIterator = this.iterator;
     const iterator: MusicPartManagerIterator = this.iterator;
+    // TODO when measure draw range (drawUpToMeasureNumber) was changed, next/update can fail to move cursor. but of course it can be reset before.
+
     const voiceEntries: VoiceEntry[] = iterator.CurrentVisibleVoiceEntries();
     const voiceEntries: VoiceEntry[] = iterator.CurrentVisibleVoiceEntries();
     if (iterator.EndReached || iterator.CurrentVoiceEntries === undefined || voiceEntries.length === 0) {
     if (iterator.EndReached || iterator.CurrentVoiceEntries === undefined || voiceEntries.length === 0) {
       return;
       return;
@@ -131,17 +160,15 @@ export class Cursor {
    */
    */
   public next(): void {
   public next(): void {
     this.iterator.moveToNext();
     this.iterator.moveToNext();
-    if (!this.hidden) {
-      this.show();
-    }
+    this.update();
   }
   }
 
 
   /**
   /**
    * reset cursor to start
    * reset cursor to start
    */
    */
   public reset(): void {
   public reset(): void {
-    this.iterator = this.manager.getIterator();
-    this.iterator.moveToNext();
+    this.resetIterator();
+    //this.iterator.moveToNext();
     this.update();
     this.update();
   }
   }