VexFlowMeasure.ts 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  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 {ClefEnum} from "../../VoiceData/Instructions/ClefInstruction";
  10. import {RhythmSymbolEnum} from "../../VoiceData/Instructions/RhythmInstruction";
  11. import {KeyEnum} from "../../VoiceData/Instructions/KeyInstruction";
  12. export class VexFlowMeasure extends StaffMeasure {
  13. constructor(staff: Staff, staffLine: StaffLine = undefined, sourceMeasure: SourceMeasure = undefined) {
  14. super(staff, sourceMeasure, staffLine);
  15. // this.MinimumStaffEntriesWidth =
  16. }
  17. private static majorMap: {[_: number]: string; } = {
  18. "0": "C", 1: "G", 2: "D", 3: "A", 4: "E", 5: "B", 6: "F#", 7: "C#",
  19. 8: "G#", "-1": "F", "-8": "Fb", "-7": "Cb", "-6": "Gb", "-5": "Db", "-4": "Ab", "-3": "Eb", "-2": "Bb",
  20. };
  21. private static minorMap: {[_: number]: string; } = {
  22. "1": "E", "7": "A#", "0": "A", "6": "D#", "3": "F#", "-5": "Bb", "-4": "F", "-7": "Ab", "-6": "Eb",
  23. "-1": "D", "4": "C#", "-3": "C", "-2": "G", "2": "B", "5": "G#", "-8": "Db", "8": "E#",
  24. };
  25. private stave: Vex.Flow.Stave;
  26. private static toVexFlowClef(clef: ClefInstruction): Vex.Flow.Clef {
  27. let type: string;
  28. switch (clef.ClefType) {
  29. case ClefEnum.G:
  30. type = "treble";
  31. break;
  32. case ClefEnum.F:
  33. type = "bass";
  34. break;
  35. case ClefEnum.C:
  36. type = "baritone-c";
  37. break;
  38. case ClefEnum.percussion:
  39. type = "percussion";
  40. break;
  41. case ClefEnum.TAB:
  42. type = "tab";
  43. break;
  44. default:
  45. }
  46. return new Vex.Flow.Clef(type);
  47. }
  48. private static toVexFlowTimeSignature(rhythm: RhythmInstruction): Vex.Flow.TimeSignature {
  49. let timeSpec: string;
  50. switch (rhythm.SymbolEnum) {
  51. case RhythmSymbolEnum.NONE:
  52. timeSpec = rhythm.Rhythm.Numerator + "/" + rhythm.Rhythm.Denominator;
  53. break;
  54. case RhythmSymbolEnum.COMMON:
  55. timeSpec = "C";
  56. break;
  57. case RhythmSymbolEnum.CUT:
  58. timeSpec = "C|";
  59. break;
  60. default:
  61. }
  62. return new Vex.Flow.TimeSignature(timeSpec);
  63. }
  64. private static toKeySignatureString(key: KeyInstruction): string {
  65. switch (key.Mode) {
  66. case KeyEnum.none:
  67. return undefined;
  68. case KeyEnum.minor:
  69. return VexFlowMeasure.minorMap[key.Key];
  70. case KeyEnum.major:
  71. return VexFlowMeasure.majorMap[key.Key] + "m";
  72. default:
  73. }
  74. }
  75. /**
  76. * Reset all the geometric values and parameters of this measure and put it in an initialized state.
  77. * This is needed to evaluate a measure a second time by system builder.
  78. */
  79. public resetLayout(): void {
  80. this.beginInstructionsWidth = 0;
  81. }
  82. /**
  83. * returns the x-width of a given measure line.
  84. * @param line
  85. * @returns {SystemLinesEnum} the x-width
  86. */
  87. public getLineWidth(line: SystemLinesEnum): number {
  88. // FIXME: See values in VexFlow's stavebarline.js
  89. switch (line) {
  90. case SystemLinesEnum.SingleThin:
  91. return 5;
  92. case SystemLinesEnum.DoubleThin:
  93. return 5;
  94. case SystemLinesEnum.ThinBold:
  95. return 5;
  96. case SystemLinesEnum.BoldThinDots:
  97. return 5;
  98. case SystemLinesEnum.DotsThinBold:
  99. return 5;
  100. case SystemLinesEnum.DotsBoldBoldDots:
  101. return 5;
  102. case SystemLinesEnum.None:
  103. return 0;
  104. default:
  105. return 0;
  106. }
  107. }
  108. /**
  109. * adds the given clef to the begin of the measure.
  110. * This has to update/increase BeginInstructionsWidth.
  111. * @param clef
  112. */
  113. public addClefAtBegin(clef: ClefInstruction): void {
  114. let vfclef: Vex.Flow.Clef = VexFlowMeasure.toVexFlowClef(clef);
  115. this.stave.addClef(vfclef, undefined, undefined, Vex.Flow.StaveModifier.Position.BEGIN);
  116. this.increaseBeginInstructionWidth(vfclef);
  117. }
  118. /**
  119. * adds the given key to the begin of the measure.
  120. * This has to update/increase BeginInstructionsWidth.
  121. * @param currentKey the new valid key.
  122. * @param previousKey the old cancelled key. Needed to show which accidentals are not valid any more.
  123. * @param currentClef the valid clef. Needed to put the accidentals on the right y-positions.
  124. */
  125. public addKeyAtBegin(currentKey: KeyInstruction, previousKey: KeyInstruction, currentClef: ClefInstruction): void {
  126. let keySig: Vex.Flow.KeySignature = new Vex.Flow.KeySignature(
  127. VexFlowMeasure.toKeySignatureString(currentKey),
  128. VexFlowMeasure.toKeySignatureString(previousKey)
  129. );
  130. this.stave.addModifier(keySig, Vex.Flow.StaveModifier.Position.BEGIN);
  131. }
  132. /**
  133. * adds the given rhythm to the begin of the measure.
  134. * This has to update/increase BeginInstructionsWidth.
  135. * @param rhythm
  136. */
  137. public addRhythmAtBegin(rhythm: RhythmInstruction): void {
  138. let timeSig: Vex.Flow.TimeSignature = VexFlowMeasure.toVexFlowTimeSignature(rhythm);
  139. this.stave.addModifier(
  140. timeSig,
  141. Vex.Flow.StaveModifier.Position.BEGIN
  142. );
  143. this.increaseBeginInstructionWidth(timeSig);
  144. }
  145. /**
  146. * adds the given clef to the end of the measure.
  147. * This has to update/increase EndInstructionsWidth.
  148. * @param clef
  149. */
  150. public addClefAtEnd(clef: ClefInstruction): void {
  151. let vfclef: Vex.Flow.Clef = VexFlowMeasure.toVexFlowClef(clef);
  152. this.stave.addClef(vfclef, undefined, undefined, Vex.Flow.StaveModifier.Position.END);
  153. this.increaseBeginInstructionWidth(vfclef);
  154. }
  155. /**
  156. * This method sets the x-position relative to the staffline. (y-Position is always 0 relative to the staffline)
  157. * @param x
  158. */
  159. public setPositionInStaffline(x: number): void {
  160. this.stave.setX(x);
  161. }
  162. /**
  163. * Sets the overall x-width of the measure.
  164. * @param width
  165. */
  166. public setWidth(width: number): void {
  167. // FIXME: this should consider modifiers!
  168. this.stave.setWidth(width);
  169. }
  170. /**
  171. * This method is called after the StaffEntriesScaleFactor has been set.
  172. * Here the final x-positions of the staff entries have to be set.
  173. * (multiply the minimal positions with the scaling factor, considering the BeginInstructionsWidth)
  174. */
  175. public layoutSymbols(): void {
  176. let min: number = 0;
  177. this.setWidth(min * this.staffEntriesScaleFactor);
  178. this.stave.format();
  179. this.stave.draw();
  180. }
  181. private increaseBeginInstructionWidth(modifier: any): void {
  182. // FIXME: Check possible paddings
  183. //this.beginInstructionsWidth += modifier.getWidth();
  184. this.beginInstructionsWidth = this.stave.getNoteStartX();
  185. }
  186. }