@coderline/alphatab 1.3.0-alpha.280 → 1.3.0-alpha.298

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/alphaTab.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * alphaTab v1.3.0-alpha.280 (develop, build 280)
2
+ * alphaTab v1.3.0-alpha.298 (develop, build 298)
3
3
  *
4
4
  * Copyright © 2022, Daniel Kuschny and Contributors, All rights reserved.
5
5
  *
@@ -4383,9 +4383,7 @@ class MasterBar {
4383
4383
  let duration = 0;
4384
4384
  for (let track of this.score.tracks) {
4385
4385
  for (let staff of track.staves) {
4386
- let barDuration = this.index < staff.bars.length
4387
- ? staff.bars[this.index].calculateDuration()
4388
- : 0;
4386
+ let barDuration = this.index < staff.bars.length ? staff.bars[this.index].calculateDuration() : 0;
4389
4387
  if (barDuration > duration) {
4390
4388
  duration = barDuration;
4391
4389
  }
@@ -4451,39 +4449,39 @@ class RepeatGroup {
4451
4449
  */
4452
4450
  this.masterBars = [];
4453
4451
  /**
4454
- * a list of masterbars which open the group.
4452
+ * the masterbars which opens the group.
4455
4453
  */
4456
- this.openings = [];
4454
+ this.opening = null;
4457
4455
  /**
4458
4456
  * a list of masterbars which close the group.
4459
4457
  */
4460
4458
  this.closings = [];
4461
- /**
4462
- * true if the repeat group was opened well
4463
- */
4464
- this.isOpened = false;
4465
4459
  /**
4466
4460
  * true if the repeat group was closed well
4467
4461
  */
4468
4462
  this.isClosed = false;
4469
4463
  }
4464
+ /**
4465
+ * a list of masterbars which open the group.
4466
+ * @deprecated There can only be one opening, use the opening property instead
4467
+ */
4468
+ get openings() {
4469
+ const opening = this.opening;
4470
+ return opening ? [opening] : [];
4471
+ }
4472
+ /**
4473
+ * Gets whether this repeat group is really opened as a repeat.
4474
+ */
4475
+ get isOpened() { var _a; return ((_a = this.opening) === null || _a === void 0 ? void 0 : _a.isRepeatStart) === true; }
4470
4476
  addMasterBar(masterBar) {
4471
- if (this.openings.length === 0) {
4472
- this.openings.push(masterBar);
4477
+ if (this.opening === null) {
4478
+ this.opening = masterBar;
4473
4479
  }
4474
4480
  this.masterBars.push(masterBar);
4475
4481
  masterBar.repeatGroup = this;
4476
4482
  if (masterBar.isRepeatEnd) {
4477
4483
  this.closings.push(masterBar);
4478
4484
  this.isClosed = true;
4479
- if (!this.isOpened) {
4480
- this.masterBars[0].isRepeatStart = true;
4481
- this.isOpened = true;
4482
- }
4483
- }
4484
- else if (this.isClosed) {
4485
- this.isClosed = false;
4486
- this.openings.push(masterBar);
4487
4485
  }
4488
4486
  }
4489
4487
  }
@@ -4497,7 +4495,9 @@ class RepeatGroup {
4497
4495
  */
4498
4496
  class Score {
4499
4497
  constructor() {
4500
- this._currentRepeatGroup = new RepeatGroup();
4498
+ this._currentRepeatGroup = null;
4499
+ this._openedRepeatGroups = [];
4500
+ this._properlyOpenedRepeatGroups = 0;
4501
4501
  /**
4502
4502
  * The album of this song.
4503
4503
  */
@@ -4562,15 +4562,11 @@ class Score {
4562
4562
  this.stylesheet = new RenderStylesheet();
4563
4563
  }
4564
4564
  rebuildRepeatGroups() {
4565
- let currentGroup = new RepeatGroup();
4566
- for (let bar of this.masterBars) {
4567
- // if the group is closed only the next upcoming header can
4568
- // reopen the group in case of a repeat alternative, so we
4569
- // remove the current group
4570
- if (bar.isRepeatStart || (this._currentRepeatGroup.isClosed && bar.alternateEndings <= 0)) {
4571
- currentGroup = new RepeatGroup();
4572
- }
4573
- currentGroup.addMasterBar(bar);
4565
+ this._currentRepeatGroup = null;
4566
+ this._openedRepeatGroups = [];
4567
+ this._properlyOpenedRepeatGroups = 0;
4568
+ for (const bar of this.masterBars) {
4569
+ this.addMasterBarToRepeatGroups(bar);
4574
4570
  }
4575
4571
  }
4576
4572
  addMasterBar(bar) {
@@ -4586,14 +4582,54 @@ class Score {
4586
4582
  bar.previousMasterBar.start +
4587
4583
  (bar.previousMasterBar.isAnacrusis ? 0 : bar.previousMasterBar.calculateDuration());
4588
4584
  }
4589
- // if the group is closed only the next upcoming header can
4590
- // reopen the group in case of a repeat alternative, so we
4591
- // remove the current group
4592
- if (bar.isRepeatStart || (this._currentRepeatGroup.isClosed && bar.alternateEndings <= 0)) {
4585
+ this.addMasterBarToRepeatGroups(bar);
4586
+ this.masterBars.push(bar);
4587
+ }
4588
+ /**
4589
+ * Adds the given bar correctly into the current repeat group setup.
4590
+ * @param bar
4591
+ */
4592
+ addMasterBarToRepeatGroups(bar) {
4593
+ // handling the repeats is quite tricky due to many invalid combinations a user might define
4594
+ // there are also some complexities due to nested repeats and repeats with multiple endings but only one opening.
4595
+ // all scenarios are handled below.
4596
+ var _a;
4597
+ // NOTE: In all paths we need to ensure that the bar is added to some repeat group
4598
+ // start a new repeat group if really a repeat is started
4599
+ // or we don't have a group.
4600
+ if (bar.isRepeatStart) {
4601
+ // if the current group was already closed (this opening doesn't cause nesting)
4602
+ // we consider the group as completed
4603
+ if ((_a = this._currentRepeatGroup) === null || _a === void 0 ? void 0 : _a.isClosed) {
4604
+ this._openedRepeatGroups.pop();
4605
+ this._properlyOpenedRepeatGroups--;
4606
+ }
4607
+ this._currentRepeatGroup = new RepeatGroup();
4608
+ this._openedRepeatGroups.push(this._currentRepeatGroup);
4609
+ this._properlyOpenedRepeatGroups++;
4610
+ }
4611
+ else if (!this._currentRepeatGroup) {
4593
4612
  this._currentRepeatGroup = new RepeatGroup();
4613
+ this._openedRepeatGroups.push(this._currentRepeatGroup);
4594
4614
  }
4615
+ // close current group if there was one started
4595
4616
  this._currentRepeatGroup.addMasterBar(bar);
4596
- this.masterBars.push(bar);
4617
+ // handle repeat ends
4618
+ if (bar.isRepeatEnd) {
4619
+ // if we have nested repeat groups a repeat end
4620
+ // will treat the group as completed
4621
+ if (this._properlyOpenedRepeatGroups > 1) {
4622
+ this._openedRepeatGroups.pop();
4623
+ this._properlyOpenedRepeatGroups--;
4624
+ // restore outer group in cases like "open open close close"
4625
+ this._currentRepeatGroup =
4626
+ this._openedRepeatGroups.length > 0
4627
+ ? this._openedRepeatGroups[this._openedRepeatGroups.length - 1]
4628
+ : null;
4629
+ }
4630
+ // else: if only one group is opened, this group stays active for
4631
+ // scenarios like open close bar close
4632
+ }
4597
4633
  }
4598
4634
  addTrack(track) {
4599
4635
  track.score = this;
@@ -12888,7 +12924,6 @@ class MusicXmlImporter extends ScoreImporter {
12888
12924
  this.mergePartGroups();
12889
12925
  }
12890
12926
  this._score.finish(this.settings);
12891
- // the structure of MusicXML does not allow live creation of the groups,
12892
12927
  this._score.rebuildRepeatGroups();
12893
12928
  return this._score;
12894
12929
  }
@@ -13616,6 +13651,11 @@ class MusicXmlImporter extends ScoreImporter {
13616
13651
  if (!slurNumber) {
13617
13652
  slurNumber = '1';
13618
13653
  }
13654
+ // slur numbers are unique in the way that they have the same ID across
13655
+ // staffs/tracks etc. as long they represent the logically same slur.
13656
+ // but in our case it must be globally unique to link the correct notes.
13657
+ // adding the staff ID should be enough to achieve this
13658
+ slurNumber = beat.voice.bar.staff.index + '_' + slurNumber;
13619
13659
  switch (c.getAttribute('type')) {
13620
13660
  case 'start':
13621
13661
  this._slurStarts.set(slurNumber, note);
@@ -13625,7 +13665,7 @@ class MusicXmlImporter extends ScoreImporter {
13625
13665
  note.isSlurDestination = true;
13626
13666
  let slurStart = this._slurStarts.get(slurNumber);
13627
13667
  slurStart.slurDestination = note;
13628
- note.slurOrigin = note;
13668
+ note.slurOrigin = slurStart;
13629
13669
  }
13630
13670
  break;
13631
13671
  }
@@ -22377,11 +22417,24 @@ var ControllerType;
22377
22417
  //PolyMode = 0x7F
22378
22418
  })(ControllerType || (ControllerType = {}));
22379
22419
 
22420
+ /**
22421
+ * Helper container to handle repeats correctly
22422
+ */
22423
+ class Repeat {
22424
+ constructor(group, opening) {
22425
+ this.closingIndex = 0;
22426
+ this.group = group;
22427
+ this.opening = opening;
22428
+ // sort ascending according to index
22429
+ group.closings = group.closings.sort((a, b) => a.index - b.index);
22430
+ this.iterations = group.closings.map(_ => 0);
22431
+ }
22432
+ }
22380
22433
  class MidiPlaybackController {
22381
22434
  constructor(score) {
22382
- this._repeatStartIndex = 0;
22383
- this._repeatNumber = 0;
22384
- this._repeatOpen = false;
22435
+ this._repeatStack = [];
22436
+ this._groupsOnStack = new Set();
22437
+ this._previousAlternateEndings = 0;
22385
22438
  this.shouldPlay = true;
22386
22439
  this.index = 0;
22387
22440
  this.currentTick = 0;
@@ -22392,25 +22445,32 @@ class MidiPlaybackController {
22392
22445
  }
22393
22446
  processCurrent() {
22394
22447
  const masterBar = this._score.masterBars[this.index];
22395
- const masterBarAlternateEndings = masterBar.alternateEndings;
22396
- // if the repeat group wasn't closed we reset the repeating
22397
- // on the last group opening
22398
- if (!masterBar.repeatGroup.isClosed &&
22399
- masterBar.repeatGroup.openings[masterBar.repeatGroup.openings.length - 1] === masterBar) {
22400
- this._repeatNumber = 0;
22401
- this._repeatOpen = false;
22402
- }
22403
- if ((masterBar.isRepeatStart || masterBar.index === 0) && this._repeatNumber === 0) {
22404
- this._repeatStartIndex = this.index;
22405
- this._repeatOpen = true;
22406
- }
22407
- else if (masterBar.isRepeatStart) {
22448
+ let masterBarAlternateEndings = masterBar.alternateEndings;
22449
+ // if there are no alternate endings set on this bar. take the ones
22450
+ // from the previously played bar which had alternate endings
22451
+ if (masterBarAlternateEndings === 0) {
22452
+ masterBarAlternateEndings = this._previousAlternateEndings;
22453
+ }
22454
+ // Repeat start (only properly closed ones)
22455
+ if (masterBar === masterBar.repeatGroup.opening && masterBar.repeatGroup.isClosed) {
22456
+ // first encounter of the repeat group? -> initialize repeats accordingly
22457
+ if (!this._groupsOnStack.has(masterBar.repeatGroup)) {
22458
+ const repeat = new Repeat(masterBar.repeatGroup, masterBar);
22459
+ this._repeatStack.push(repeat);
22460
+ this._groupsOnStack.add(masterBar.repeatGroup);
22461
+ this._previousAlternateEndings = 0;
22462
+ }
22463
+ }
22464
+ // if we're not within repeats or not alternative endings set -> simply play
22465
+ if (this._repeatStack.length === 0 || masterBarAlternateEndings === 0) {
22408
22466
  this.shouldPlay = true;
22409
22467
  }
22410
- // if we encounter an alternate ending
22411
- if (this._repeatOpen && masterBarAlternateEndings > 0) {
22468
+ else {
22469
+ const repeat = this._repeatStack[this._repeatStack.length - 1];
22470
+ const iteration = repeat.iterations[repeat.closingIndex];
22471
+ this._previousAlternateEndings = masterBarAlternateEndings;
22412
22472
  // do we need to skip this section?
22413
- if ((masterBarAlternateEndings & (1 << this._repeatNumber)) === 0) {
22473
+ if ((masterBarAlternateEndings & (1 << iteration)) === 0) {
22414
22474
  this.shouldPlay = false;
22415
22475
  }
22416
22476
  else {
@@ -22424,23 +22484,42 @@ class MidiPlaybackController {
22424
22484
  moveNext() {
22425
22485
  const masterBar = this._score.masterBars[this.index];
22426
22486
  const masterBarRepeatCount = masterBar.repeatCount - 1;
22427
- // if we encounter a repeat end
22428
- if (this._repeatOpen && masterBarRepeatCount > 0) {
22429
- // more repeats required?
22430
- if (this._repeatNumber < masterBarRepeatCount) {
22487
+ // if we encounter a repeat end...
22488
+ if (this._repeatStack.length > 0 && masterBarRepeatCount > 0) {
22489
+ // ...more repeats required?
22490
+ const repeat = this._repeatStack[this._repeatStack.length - 1];
22491
+ const iteration = repeat.iterations[repeat.closingIndex];
22492
+ // -> if yes, increase the iteration and jump back to start
22493
+ if (iteration < masterBarRepeatCount) {
22431
22494
  // jump to start
22432
- this.index = this._repeatStartIndex;
22433
- this._repeatNumber++;
22495
+ this.index = repeat.opening.index;
22496
+ repeat.iterations[repeat.closingIndex]++;
22497
+ // clear iterations for previous closings and start over all repeats
22498
+ // this ensures on scenarios like "open, bar, close, bar, close"
22499
+ // that the second close will repeat again the first repeat.
22500
+ for (let i = 0; i < repeat.closingIndex; i++) {
22501
+ repeat.iterations[i] = 0;
22502
+ }
22503
+ repeat.closingIndex = 0;
22504
+ this._previousAlternateEndings = 0;
22434
22505
  }
22435
22506
  else {
22436
- // no repeats anymore, jump after repeat end
22437
- this._repeatNumber = 0;
22438
- this._repeatOpen = false;
22439
- this.shouldPlay = true;
22440
- this.index++;
22507
+ // if we don't have further iterations left but we have additional closings in this group
22508
+ // proceed heading to the next close but keep the repeat group active
22509
+ if (repeat.closingIndex < repeat.group.closings.length - 1) {
22510
+ repeat.closingIndex++;
22511
+ this.index++; // go to next bar after current close
22512
+ }
22513
+ else {
22514
+ // if there are no further closings in the current group, we consider the current repeat done and handled
22515
+ this._repeatStack.pop();
22516
+ this._groupsOnStack.delete(repeat.group);
22517
+ this.index++; // go to next bar after current close
22518
+ }
22441
22519
  }
22442
22520
  }
22443
22521
  else {
22522
+ // we have no started repeat, just proceed to next bar
22444
22523
  this.index++;
22445
22524
  }
22446
22525
  }
@@ -24118,6 +24197,15 @@ class ResizeEventArgs {
24118
24197
  }
24119
24198
  }
24120
24199
 
24200
+ /**
24201
+ * Represents the information related to the beats actively being played now.
24202
+ */
24203
+ class ActiveBeatsChangedEventArgs {
24204
+ constructor(activeBeats) {
24205
+ this.activeBeats = activeBeats;
24206
+ }
24207
+ }
24208
+
24121
24209
  class SelectionInfo {
24122
24210
  constructor(beat) {
24123
24211
  this.bounds = null;
@@ -24165,6 +24253,7 @@ class AlphaTabApiBase {
24165
24253
  this._previousCursorCache = null;
24166
24254
  this._lastScroll = 0;
24167
24255
  this.playedBeatChanged = new EventEmitterOfT();
24256
+ this.activeBeatsChanged = new EventEmitterOfT();
24168
24257
  this._beatMouseDown = false;
24169
24258
  this._noteMouseDown = false;
24170
24259
  this._selectionStart = null;
@@ -24190,6 +24279,10 @@ class AlphaTabApiBase {
24190
24279
  this.playerPositionChanged = new EventEmitterOfT();
24191
24280
  this.midiEventsPlayed = new EventEmitterOfT();
24192
24281
  this.playbackRangeChanged = new EventEmitterOfT();
24282
+ /**
24283
+ * @internal
24284
+ */
24285
+ this.settingsUpdated = new EventEmitter();
24193
24286
  this.uiFacade = uiFacade;
24194
24287
  this.container = uiFacade.rootContainer;
24195
24288
  uiFacade.initialize(this, settings);
@@ -24268,6 +24361,7 @@ class AlphaTabApiBase {
24268
24361
  else {
24269
24362
  this.destroyPlayer();
24270
24363
  }
24364
+ this.onSettingsUpdated();
24271
24365
  }
24272
24366
  /**
24273
24367
  * Attempts a load of the score represented by the given data object.
@@ -24579,9 +24673,12 @@ class AlphaTabApiBase {
24579
24673
  }
24580
24674
  this.player.destroy();
24581
24675
  this.player = null;
24676
+ this._previousTick = 0;
24677
+ this._playerState = PlayerState.Paused;
24582
24678
  this.destroyCursors();
24583
24679
  }
24584
24680
  setupPlayer() {
24681
+ this.updateCursors();
24585
24682
  if (this.player) {
24586
24683
  return;
24587
24684
  }
@@ -24615,12 +24712,7 @@ class AlphaTabApiBase {
24615
24712
  this.player.midiEventsPlayed.on(this.onMidiEventsPlayed.bind(this));
24616
24713
  this.player.playbackRangeChanged.on(this.onPlaybackRangeChanged.bind(this));
24617
24714
  this.player.finished.on(this.onPlayerFinished.bind(this));
24618
- if (this.settings.player.enableCursor) {
24619
- this.setupCursors();
24620
- }
24621
- else {
24622
- this.destroyCursors();
24623
- }
24715
+ this.setupPlayerEvents();
24624
24716
  }
24625
24717
  loadMidiForScore() {
24626
24718
  if (!this.player || !this.score || !this.player.isReady) {
@@ -24754,21 +24846,28 @@ class AlphaTabApiBase {
24754
24846
  this._barCursor = null;
24755
24847
  this._beatCursor = null;
24756
24848
  this._selectionWrapper = null;
24757
- this._previousTick = 0;
24758
- this._playerState = PlayerState.Paused;
24759
24849
  }
24760
- setupCursors() {
24761
- //
24762
- // Create cursors
24763
- let cursors = this.uiFacade.createCursors();
24764
- if (!cursors) {
24765
- return;
24850
+ updateCursors() {
24851
+ if (this.settings.player.enableCursor && !this._cursorWrapper) {
24852
+ //
24853
+ // Create cursors
24854
+ let cursors = this.uiFacade.createCursors();
24855
+ if (cursors) {
24856
+ // store options and created elements for fast access
24857
+ this._cursorWrapper = cursors.cursorWrapper;
24858
+ this._barCursor = cursors.barCursor;
24859
+ this._beatCursor = cursors.beatCursor;
24860
+ this._selectionWrapper = cursors.selectionWrapper;
24861
+ }
24862
+ if (this._currentBeat !== null) {
24863
+ this.cursorUpdateBeat(this._currentBeat, false, this._previousTick > 10, true);
24864
+ }
24865
+ }
24866
+ else if (!this.settings.player.enableCursor && this._cursorWrapper) {
24867
+ this.destroyCursors();
24766
24868
  }
24767
- // store options and created elements for fast access
24768
- this._cursorWrapper = cursors.cursorWrapper;
24769
- this._barCursor = cursors.barCursor;
24770
- this._beatCursor = cursors.beatCursor;
24771
- this._selectionWrapper = cursors.selectionWrapper;
24869
+ }
24870
+ setupPlayerEvents() {
24772
24871
  //
24773
24872
  // Hook into events
24774
24873
  this._previousTick = 0;
@@ -24819,7 +24918,7 @@ class AlphaTabApiBase {
24819
24918
  /**
24820
24919
  * updates the cursors to highlight the specified beat
24821
24920
  */
24822
- cursorUpdateBeat(lookupResult, stop, shouldScroll) {
24921
+ cursorUpdateBeat(lookupResult, stop, shouldScroll, forceUpdate = false) {
24823
24922
  const beat = lookupResult.currentBeat;
24824
24923
  const nextBeat = lookupResult.nextBeat;
24825
24924
  const duration = lookupResult.duration;
@@ -24834,7 +24933,10 @@ class AlphaTabApiBase {
24834
24933
  let previousBeat = this._currentBeat;
24835
24934
  let previousCache = this._previousCursorCache;
24836
24935
  let previousState = this._previousStateForCursor;
24837
- if (beat === (previousBeat === null || previousBeat === void 0 ? void 0 : previousBeat.currentBeat) && cache === previousCache && previousState === this._playerState) {
24936
+ if (!forceUpdate &&
24937
+ beat === (previousBeat === null || previousBeat === void 0 ? void 0 : previousBeat.currentBeat) &&
24938
+ cache === previousCache &&
24939
+ previousState === this._playerState) {
24838
24940
  return;
24839
24941
  }
24840
24942
  let beatBoundings = cache.findBeat(beat);
@@ -24911,17 +25013,21 @@ class AlphaTabApiBase {
24911
25013
  }
24912
25014
  }
24913
25015
  internalCursorUpdateBeat(beat, nextBeat, duration, stop, beatsToHighlight, cache, beatBoundings, shouldScroll) {
24914
- let barCursor = this._barCursor;
24915
- let beatCursor = this._beatCursor;
25016
+ const barCursor = this._barCursor;
25017
+ const beatCursor = this._beatCursor;
24916
25018
  let barBoundings = beatBoundings.barBounds.masterBarBounds;
24917
25019
  let barBounds = barBoundings.visualBounds;
24918
25020
  this._currentBarBounds = barBoundings;
24919
- barCursor.setBounds(barBounds.x, barBounds.y, barBounds.w, barBounds.h);
24920
- // move beat to start position immediately
24921
- if (this.settings.player.enableAnimatedBeatCursor) {
24922
- beatCursor.stopAnimation();
25021
+ if (barCursor) {
25022
+ barCursor.setBounds(barBounds.x, barBounds.y, barBounds.w, barBounds.h);
25023
+ }
25024
+ if (beatCursor) {
25025
+ // move beat to start position immediately
25026
+ if (this.settings.player.enableAnimatedBeatCursor) {
25027
+ beatCursor.stopAnimation();
25028
+ }
25029
+ beatCursor.setBounds(beatBoundings.visualBounds.x, barBounds.y, 1, barBounds.h);
24923
25030
  }
24924
- beatCursor.setBounds(beatBoundings.visualBounds.x, barBounds.y, 1, barBounds.h);
24925
25031
  // if playing, animate the cursor to the next beat
24926
25032
  if (this.settings.player.enableElementHighlighting) {
24927
25033
  this.uiFacade.removeHighlights();
@@ -24929,7 +25035,7 @@ class AlphaTabApiBase {
24929
25035
  // actively playing? -> animate cursor and highlight items
24930
25036
  let shouldNotifyBeatChange = false;
24931
25037
  if (this._playerState === PlayerState.Playing && !stop) {
24932
- if (this.settings.player.enableElementHighlighting && beatsToHighlight) {
25038
+ if (this.settings.player.enableElementHighlighting) {
24933
25039
  for (let highlight of beatsToHighlight) {
24934
25040
  let className = BeatContainerGlyph.getGroupId(highlight);
24935
25041
  this.uiFacade.highlightElements(className, beat.voice.bar.index);
@@ -24954,7 +25060,9 @@ class AlphaTabApiBase {
24954
25060
  // we need to put the transition to an own animation frame
24955
25061
  // otherwise the stop animation above is not applied.
24956
25062
  this.uiFacade.beginInvoke(() => {
24957
- beatCursor.transitionToX(duration / this.playbackSpeed, nextBeatX);
25063
+ if (beatCursor) {
25064
+ beatCursor.transitionToX(duration / this.playbackSpeed, nextBeatX);
25065
+ }
24958
25066
  });
24959
25067
  }
24960
25068
  shouldScroll = !stop;
@@ -24966,6 +25074,7 @@ class AlphaTabApiBase {
24966
25074
  // trigger an event for others to indicate which beat/bar is played
24967
25075
  if (shouldNotifyBeatChange) {
24968
25076
  this.onPlayedBeatChanged(beat);
25077
+ this.onActiveBeatsChanged(new ActiveBeatsChangedEventArgs(beatsToHighlight));
24969
25078
  }
24970
25079
  }
24971
25080
  onPlayedBeatChanged(beat) {
@@ -24975,6 +25084,13 @@ class AlphaTabApiBase {
24975
25084
  this.playedBeatChanged.trigger(beat);
24976
25085
  this.uiFacade.triggerEvent(this.container, 'playedBeatChanged', beat);
24977
25086
  }
25087
+ onActiveBeatsChanged(e) {
25088
+ if (this._isDestroyed) {
25089
+ return;
25090
+ }
25091
+ this.activeBeatsChanged.trigger(e);
25092
+ this.uiFacade.triggerEvent(this.container, 'activeBeatsChanged', e);
25093
+ }
24978
25094
  onBeatMouseDown(originalEvent, beat) {
24979
25095
  if (this._isDestroyed) {
24980
25096
  return;
@@ -25334,6 +25450,13 @@ class AlphaTabApiBase {
25334
25450
  this.playbackRangeChanged.trigger(e);
25335
25451
  this.uiFacade.triggerEvent(this.container, 'playbackRangeChanged', e);
25336
25452
  }
25453
+ onSettingsUpdated() {
25454
+ if (this._isDestroyed) {
25455
+ return;
25456
+ }
25457
+ this.settingsUpdated.trigger();
25458
+ this.uiFacade.triggerEvent(this.container, 'settingsUpdated', null);
25459
+ }
25337
25460
  }
25338
25461
 
25339
25462
  /**
@@ -37399,13 +37522,13 @@ class ScoreBarRenderer extends BarRendererBase {
37399
37522
  offsetClef = 1;
37400
37523
  break;
37401
37524
  case Clef.F4:
37402
- offsetClef = 2;
37525
+ offsetClef = 3;
37403
37526
  break;
37404
37527
  case Clef.C3:
37405
- offsetClef = -1;
37528
+ offsetClef = 2;
37406
37529
  break;
37407
37530
  case Clef.C4:
37408
- offsetClef = 1;
37531
+ offsetClef = 0;
37409
37532
  break;
37410
37533
  }
37411
37534
  let newLines = new Map();
@@ -40855,8 +40978,8 @@ class CoreSettings {
40855
40978
  // </auto-generated>
40856
40979
  class VersionInfo {
40857
40980
  }
40858
- VersionInfo.version = '1.3.0-alpha.280';
40859
- VersionInfo.date = '2022-05-26T00:48:53.664Z';
40981
+ VersionInfo.version = '1.3.0-alpha.298';
40982
+ VersionInfo.date = '2022-06-13T00:49:52.818Z';
40860
40983
 
40861
40984
  var index$5 = /*#__PURE__*/Object.freeze({
40862
40985
  __proto__: null,
@@ -43925,6 +44048,7 @@ var index = /*#__PURE__*/Object.freeze({
43925
44048
  PlayerStateChangedEventArgs: PlayerStateChangedEventArgs,
43926
44049
  PlaybackRangeChangedEventArgs: PlaybackRangeChangedEventArgs,
43927
44050
  PositionChangedEventArgs: PositionChangedEventArgs,
44051
+ ActiveBeatsChangedEventArgs: ActiveBeatsChangedEventArgs,
43928
44052
  AlphaSynthWebWorkerApi: AlphaSynthWebWorkerApi
43929
44053
  });
43930
44054
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coderline/alphatab",
3
- "version": "1.3.0-alpha.280",
3
+ "version": "1.3.0-alpha.298",
4
4
  "description": "alphaTab is a music notation and guitar tablature rendering library",
5
5
  "keywords": [
6
6
  "guitar",
@@ -66,16 +66,16 @@
66
66
  "karma-chrome-launcher": "^3.1.1",
67
67
  "karma-express-http-server": "0.0.1",
68
68
  "karma-jasmine": "^5.0.1",
69
- "karma-jasmine-html-reporter": "^1.7.0",
69
+ "karma-jasmine-html-reporter": "^2.0.0",
70
70
  "karma-rollup-preprocessor": "^7.0.8",
71
71
  "karma-spec-reporter": "0.0.34",
72
72
  "lodash": "^4.17.21",
73
73
  "multer": "^1.4.4",
74
74
  "rimraf": "^3.0.2",
75
- "rollup": "^2.74.1",
75
+ "rollup": "^2.75.1",
76
76
  "rollup-plugin-copy": "^3.4.0",
77
- "rollup-plugin-dts": "^4.2.1",
78
- "rollup-plugin-license": "^2.7.0",
77
+ "rollup-plugin-dts": "^4.2.2",
78
+ "rollup-plugin-license": "^2.8.0",
79
79
  "rollup-plugin-serve": "^1.1.0",
80
80
  "rollup-plugin-terser": "^7.0.2",
81
81
  "terser": "^5.13.1",