VexFlowMeasure.ts 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. import {StaffMeasure} from "../StaffMeasure";
  2. import {SourceMeasure} from "../../VoiceData/SourceMeasure";
  3. import {Staff} from "../../VoiceData/Staff";
  4. import {StaffLine} from "../StaffLine";
  5. import {SystemLinesEnum} from "../SystemLinesEnum";
  6. import {ClefInstruction} from "../../VoiceData/Instructions/ClefInstruction";
  7. import {KeyInstruction} from "../../VoiceData/Instructions/KeyInstruction";
  8. import {RhythmInstruction} from "../../VoiceData/Instructions/RhythmInstruction";
  9. import {VexFlowConverter} from "./VexFlowConverter";
  10. export class VexFlowMeasure extends StaffMeasure {
  11. constructor(staff: Staff, staffLine: StaffLine = undefined, sourceMeasure: SourceMeasure = undefined) {
  12. super(staff, sourceMeasure, staffLine);
  13. // this.MinimumStaffEntriesWidth =
  14. }
  15. public stave: Vex.Flow.Stave;
  16. /**
  17. * Reset all the geometric values and parameters of this measure and put it in an initialized state.
  18. * This is needed to evaluate a measure a second time by system builder.
  19. */
  20. public resetLayout(): void {
  21. this.beginInstructionsWidth = 0;
  22. }
  23. /**
  24. * returns the x-width of a given measure line.
  25. * @param line
  26. * @returns {SystemLinesEnum} the x-width
  27. */
  28. public getLineWidth(line: SystemLinesEnum): number {
  29. // FIXME: See values in VexFlow's stavebarline.js
  30. switch (line) {
  31. case SystemLinesEnum.SingleThin:
  32. return 5;
  33. case SystemLinesEnum.DoubleThin:
  34. return 5;
  35. case SystemLinesEnum.ThinBold:
  36. return 5;
  37. case SystemLinesEnum.BoldThinDots:
  38. return 5;
  39. case SystemLinesEnum.DotsThinBold:
  40. return 5;
  41. case SystemLinesEnum.DotsBoldBoldDots:
  42. return 5;
  43. case SystemLinesEnum.None:
  44. return 0;
  45. default:
  46. return 0;
  47. }
  48. }
  49. /**
  50. * adds the given clef to the begin of the measure.
  51. * This has to update/increase BeginInstructionsWidth.
  52. * @param clef
  53. */
  54. public addClefAtBegin(clef: ClefInstruction): void {
  55. let vfclef: Vex.Flow.Clef = VexFlowConverter.Clef(clef);
  56. this.stave.addClef(vfclef, undefined, undefined, Vex.Flow.StaveModifier.Position.BEGIN);
  57. this.increaseBeginInstructionWidth(vfclef);
  58. }
  59. /**
  60. * adds the given key to the begin of the measure.
  61. * This has to update/increase BeginInstructionsWidth.
  62. * @param currentKey the new valid key.
  63. * @param previousKey the old cancelled key. Needed to show which accidentals are not valid any more.
  64. * @param currentClef the valid clef. Needed to put the accidentals on the right y-positions.
  65. */
  66. public addKeyAtBegin(currentKey: KeyInstruction, previousKey: KeyInstruction, currentClef: ClefInstruction): void {
  67. let keySig: Vex.Flow.KeySignature = new Vex.Flow.KeySignature(
  68. VexFlowConverter.keySignature(currentKey),
  69. VexFlowConverter.keySignature(previousKey)
  70. );
  71. this.stave.addModifier(keySig, Vex.Flow.StaveModifier.Position.BEGIN);
  72. }
  73. /**
  74. * adds the given rhythm to the begin of the measure.
  75. * This has to update/increase BeginInstructionsWidth.
  76. * @param rhythm
  77. */
  78. public addRhythmAtBegin(rhythm: RhythmInstruction): void {
  79. let timeSig: Vex.Flow.TimeSignature = VexFlowConverter.TimeSignature(rhythm);
  80. this.stave.addModifier(
  81. timeSig,
  82. Vex.Flow.StaveModifier.Position.BEGIN
  83. );
  84. this.increaseBeginInstructionWidth(timeSig);
  85. }
  86. /**
  87. * adds the given clef to the end of the measure.
  88. * This has to update/increase EndInstructionsWidth.
  89. * @param clef
  90. */
  91. public addClefAtEnd(clef: ClefInstruction): void {
  92. let vfclef: Vex.Flow.Clef = VexFlowConverter.Clef(clef);
  93. this.stave.addClef(vfclef, undefined, undefined, Vex.Flow.StaveModifier.Position.END);
  94. this.increaseBeginInstructionWidth(vfclef);
  95. }
  96. /**
  97. * This method sets the x-position relative to the staffline. (y-Position is always 0 relative to the staffline)
  98. * @param x
  99. */
  100. public setPositionInStaffline(x: number): void {
  101. this.stave.setX(x);
  102. }
  103. /**
  104. * Sets the overall x-width of the measure.
  105. * @param width
  106. */
  107. public setWidth(width: number): void {
  108. // FIXME: this should consider modifiers!
  109. this.stave.setWidth(width);
  110. }
  111. /**
  112. * This method is called after the StaffEntriesScaleFactor has been set.
  113. * Here the final x-positions of the staff entries have to be set.
  114. * (multiply the minimal positions with the scaling factor, considering the BeginInstructionsWidth)
  115. */
  116. public layoutSymbols(): void {
  117. let min: number = 0;
  118. this.setWidth(min * this.staffEntriesScaleFactor);
  119. this.stave.format();
  120. this.stave.draw();
  121. }
  122. public getVexFlowVoices(): { [id: number]: Vex.Flow.Voice; } {
  123. let notes: { [id: number]: Vex.Flow.StaveNote[]; } = {};
  124. for (let entry of this.staffEntries) {
  125. for (let voiceEntry of entry.sourceStaffEntry.VoiceEntries) {
  126. let id: number = voiceEntry.ParentVoice.VoiceId;
  127. if (!(id in notes)) {
  128. notes[id] = [];
  129. }
  130. notes[id].push(VexFlowConverter.StaveNote(voiceEntry));
  131. }
  132. }
  133. let voices: { [id: number]: Vex.Flow.Voice; } = {};
  134. let num: number = this.parentSourceMeasure.Duration.Numerator;
  135. let den: number = this.parentSourceMeasure.Duration.Denominator;
  136. for (let id in notes) {
  137. if (notes.hasOwnProperty(id)) {
  138. let voice: Vex.Flow.Voice = new Vex.Flow.Voice({
  139. beat_value: den,
  140. num_beats: num,
  141. resolution: Vex.Flow.RESOLUTION,
  142. });
  143. voice.addTickables(notes[id]);
  144. voices[id] = voice;
  145. }
  146. }
  147. return voices;
  148. }
  149. private increaseBeginInstructionWidth(modifier: any): void {
  150. // FIXME: Check possible paddings...
  151. //this.beginInstructionsWidth += modifier.getWidth();
  152. this.beginInstructionsWidth = this.stave.getNoteStartX();
  153. }
  154. }