@coderline/alphatab 1.8.0-alpha.1636 → 1.8.0-alpha.1637

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.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * alphaTab v1.8.0-alpha.1636 (develop, build 1636)
2
+ * alphaTab v1.8.0-alpha.1637 (develop, build 1637)
3
3
  *
4
4
  * Copyright © 2025, Daniel Kuschny and Contributors, All rights reserved.
5
5
  *
@@ -203,9 +203,9 @@ class AlphaTabError extends Error {
203
203
  * @internal
204
204
  */
205
205
  class VersionInfo {
206
- static version = '1.8.0-alpha.1636';
207
- static date = '2025-12-06T02:04:52.462Z';
208
- static commit = '49c68ed64403080028c852fe371cc6bdcca8dc3a';
206
+ static version = '1.8.0-alpha.1637';
207
+ static date = '2025-12-07T02:26:27.382Z';
208
+ static commit = 'aa2c8101456d3ddfc777491468bc483789cc6c12';
209
209
  static print(print) {
210
210
  print(`alphaTab ${VersionInfo.version}`);
211
211
  print(`commit: ${VersionInfo.commit}`);
@@ -12950,25 +12950,31 @@ class Bounds {
12950
12950
  /**
12951
12951
  * Gets or sets the X-position of the rectangle within the music notation.
12952
12952
  */
12953
- x = 0;
12953
+ x;
12954
12954
  /**
12955
12955
  * Gets or sets the Y-position of the rectangle within the music notation.
12956
12956
  */
12957
- y = 0;
12957
+ y;
12958
12958
  /**
12959
12959
  * Gets or sets the width of the rectangle.
12960
12960
  */
12961
- w = 0;
12961
+ w;
12962
12962
  /**
12963
12963
  * Gets or sets the height of the rectangle.
12964
12964
  */
12965
- h = 0;
12965
+ h;
12966
12966
  scaleWith(scale) {
12967
12967
  this.x *= scale;
12968
12968
  this.y *= scale;
12969
12969
  this.w *= scale;
12970
12970
  this.h *= scale;
12971
12971
  }
12972
+ constructor(x = 0, y = 0, w = 0, h = 0) {
12973
+ this.x = x;
12974
+ this.y = y;
12975
+ this.h = h;
12976
+ this.w = w;
12977
+ }
12972
12978
  }
12973
12979
 
12974
12980
  /**
@@ -49454,16 +49460,6 @@ class ExternalMediaPlayer extends BackingTrackPlayer {
49454
49460
  }
49455
49461
  }
49456
49462
 
49457
- /**
49458
- * @internal
49459
- */
49460
- class SelectionInfo {
49461
- beat;
49462
- bounds = null;
49463
- constructor(beat) {
49464
- this.beat = beat;
49465
- }
49466
- }
49467
49463
  /**
49468
49464
  * This class represents the public API of alphaTab and provides all logic to display
49469
49465
  * a music sheet in any UI using the given {@link IUiFacade}
@@ -51563,8 +51559,8 @@ class AlphaTabApiBase {
51563
51559
  }
51564
51560
  _isBeatMouseDown = false;
51565
51561
  _isNoteMouseDown = false;
51566
- _selectionStart = null;
51567
- _selectionEnd = null;
51562
+ _selectionStart;
51563
+ _selectionEnd;
51568
51564
  /**
51569
51565
  * This event is fired whenever a the user presses the mouse button on a beat.
51570
51566
  * @eventProperty
@@ -51807,8 +51803,8 @@ class AlphaTabApiBase {
51807
51803
  return;
51808
51804
  }
51809
51805
  if (this._hasCursor && this.settings.player.enableUserInteraction) {
51810
- this._selectionStart = new SelectionInfo(beat);
51811
- this._selectionEnd = null;
51806
+ this._selectionStart = { beat };
51807
+ this._selectionEnd = undefined;
51812
51808
  }
51813
51809
  this._isBeatMouseDown = true;
51814
51810
  this.beatMouseDown.trigger(beat);
@@ -51828,7 +51824,7 @@ class AlphaTabApiBase {
51828
51824
  }
51829
51825
  if (this.settings.player.enableUserInteraction) {
51830
51826
  if (!this._selectionEnd || this._selectionEnd.beat !== beat) {
51831
- this._selectionEnd = new SelectionInfo(beat);
51827
+ this._selectionEnd = { beat };
51832
51828
  this._cursorSelectRange(this._selectionStart, this._selectionEnd);
51833
51829
  }
51834
51830
  }
@@ -51847,45 +51843,7 @@ class AlphaTabApiBase {
51847
51843
  return;
51848
51844
  }
51849
51845
  if (this._hasCursor && this.settings.player.enableUserInteraction) {
51850
- if (this._selectionEnd) {
51851
- const startTick = this._tickCache?.getBeatStart(this._selectionStart.beat) ??
51852
- this._selectionStart.beat.absolutePlaybackStart;
51853
- const endTick = this._tickCache?.getBeatStart(this._selectionEnd.beat) ??
51854
- this._selectionEnd.beat.absolutePlaybackStart;
51855
- if (endTick < startTick) {
51856
- const t = this._selectionStart;
51857
- this._selectionStart = this._selectionEnd;
51858
- this._selectionEnd = t;
51859
- }
51860
- }
51861
- if (this._selectionStart && this._tickCache) {
51862
- // get the start and stop ticks (which consider properly repeats)
51863
- const tickCache = this._tickCache;
51864
- const realMasterBarStart = tickCache.getMasterBarStart(this._selectionStart.beat.voice.bar.masterBar);
51865
- // move to selection start
51866
- this._currentBeat = null; // reset current beat so it is updating the cursor
51867
- if (this._player.state === PlayerState.Paused) {
51868
- this._cursorUpdateTick(this._tickCache.getBeatStart(this._selectionStart.beat), false, 1);
51869
- }
51870
- this.tickPosition = realMasterBarStart + this._selectionStart.beat.playbackStart;
51871
- // set playback range
51872
- if (this._selectionEnd && this._selectionStart.beat !== this._selectionEnd.beat) {
51873
- const realMasterBarEnd = tickCache.getMasterBarStart(this._selectionEnd.beat.voice.bar.masterBar);
51874
- const range = new PlaybackRange();
51875
- range.startTick = realMasterBarStart + this._selectionStart.beat.playbackStart;
51876
- range.endTick =
51877
- realMasterBarEnd +
51878
- this._selectionEnd.beat.playbackStart +
51879
- this._selectionEnd.beat.playbackDuration -
51880
- 50;
51881
- this.playbackRange = range;
51882
- }
51883
- else {
51884
- this._selectionStart = null;
51885
- this.playbackRange = null;
51886
- this._cursorSelectRange(this._selectionStart, this._selectionEnd);
51887
- }
51888
- }
51846
+ this.applyPlaybackRangeFromHighlight();
51889
51847
  }
51890
51848
  this.beatMouseUp.trigger(beat);
51891
51849
  this.uiFacade.triggerEvent(this.container, 'beatMouseUp', beat, originalEvent);
@@ -51907,13 +51865,13 @@ class AlphaTabApiBase {
51907
51865
  const startBeat = this._tickCache.findBeat(this._trackIndexLookup, range.startTick);
51908
51866
  const endBeat = this._tickCache.findBeat(this._trackIndexLookup, range.endTick);
51909
51867
  if (startBeat && endBeat) {
51910
- const selectionStart = new SelectionInfo(startBeat.beat);
51911
- const selectionEnd = new SelectionInfo(endBeat.beat);
51868
+ const selectionStart = { beat: startBeat.beat };
51869
+ const selectionEnd = { beat: endBeat.beat };
51912
51870
  this._cursorSelectRange(selectionStart, selectionEnd);
51913
51871
  }
51914
51872
  }
51915
51873
  else {
51916
- this._cursorSelectRange(null, null);
51874
+ this._cursorSelectRange(undefined, undefined);
51917
51875
  }
51918
51876
  }
51919
51877
  _setupClickHandling() {
@@ -51982,24 +51940,230 @@ class AlphaTabApiBase {
51982
51940
  this._cursorSelectRange(this._selectionStart, this._selectionEnd);
51983
51941
  });
51984
51942
  }
51943
+ /**
51944
+ * Places the highlight markers at the specified start and end-beat range.
51945
+ * @param startBeat The start beat where the selection should start
51946
+ * @param endBeat The end beat where the selection should end.
51947
+ *
51948
+ * @remarks
51949
+ * Unlike actually setting {@link playbackRange} this method only places the selection markers without actually
51950
+ * changing the playback range. This method can be used when building custom selection systems (e.g. having draggable handles).
51951
+ *
51952
+ * @category Methods - Player
51953
+ * @since 1.8.0
51954
+ *
51955
+ * @example
51956
+ * JavaScript
51957
+ * ```js
51958
+ * const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab'));
51959
+ * const startBeat = api.score.tracks[0].staves[0].bars[0].voices[0].beats[0];
51960
+ * const endBeat = api.score.tracks[0].staves[0].bars[3].voices[0].beats[0];
51961
+ * api.highlightPlaybackRange(startBeat, endBeat);
51962
+ * ```
51963
+ *
51964
+ * @example
51965
+ * C#
51966
+ * ```cs
51967
+ * var api = new AlphaTabApi<MyControl>(...);
51968
+ * api.ChangeTrackVolume(new Track[] { api.Score.Tracks[0], api.Score.Tracks[1] }, 1.5);
51969
+ * api.ChangeTrackVolume(new Track[] { api.Score.Tracks[2] }, 0.5);
51970
+ * var startBeat = api.Score.Tracks[0].Staves[0].Bars[0].Voices[0].Beats[0];
51971
+ * var endBeat = api.Score.Tracks[0].Staves[0].Bars[3].Voices[0].Beats[0];
51972
+ * api.HighlightPlaybackRange(startBeat, endBeat);
51973
+ * ```
51974
+ *
51975
+ * @example
51976
+ * Android
51977
+ * ```kotlin
51978
+ * val api = AlphaTabApi<MyControl>(...)
51979
+ * val startBeat = api.score.tracks[0].staves[0].bars[0].voices[0].beats[0]
51980
+ * val endBeat = api.score.tracks[0].staves[0].bars[3].voices[0].beats[0]
51981
+ * api.highlightPlaybackRange(startBeat, endBeat)
51982
+ * ```
51983
+ */
51984
+ highlightPlaybackRange(startBeat, endBeat) {
51985
+ this._selectionStart = { beat: startBeat };
51986
+ this._selectionEnd = { beat: endBeat };
51987
+ this._cursorSelectRange(this._selectionStart, this._selectionEnd);
51988
+ }
51989
+ /**
51990
+ * Applies the playback range from the currently highlighted range.
51991
+ *
51992
+ * @remarks
51993
+ * This method can be used when building custom selection systems (e.g. having draggable handles).
51994
+ *
51995
+ * @category Methods - Player
51996
+ * @since 1.8.0
51997
+ *
51998
+ * @example
51999
+ * JavaScript
52000
+ * ```js
52001
+ * const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab'));
52002
+ * const startBeat = api.score.tracks[0].staves[0].bars[0].voices[0].beats[0];
52003
+ * const endBeat = api.score.tracks[0].staves[0].bars[3].voices[0].beats[0];
52004
+ * api.highlightPlaybackRange(startBeat, endBeat);
52005
+ * api.applyPlaybackRangeFromHighlight();
52006
+ * ```
52007
+ *
52008
+ * @example
52009
+ * C#
52010
+ * ```cs
52011
+ * var api = new AlphaTabApi<MyControl>(...);
52012
+ * api.ChangeTrackVolume(new Track[] { api.Score.Tracks[0], api.Score.Tracks[1] }, 1.5);
52013
+ * api.ChangeTrackVolume(new Track[] { api.Score.Tracks[2] }, 0.5);
52014
+ * var startBeat = api.Score.Tracks[0].Staves[0].Bars[0].Voices[0].Beats[0];
52015
+ * var endBeat = api.Score.Tracks[0].Staves[0].Bars[3].Voices[0].Beats[0];
52016
+ * api.HighlightPlaybackRange(startBeat, endBeat);
52017
+ * api.ApplyPlaybackRangeFromHighlight();
52018
+ * ```
52019
+ *
52020
+ * @example
52021
+ * Android
52022
+ * ```kotlin
52023
+ * val api = AlphaTabApi<MyControl>(...)
52024
+ * val startBeat = api.score.tracks[0].staves[0].bars[0].voices[0].beats[0]
52025
+ * val endBeat = api.score.tracks[0].staves[0].bars[3].voices[0].beats[0]
52026
+ * api.highlightPlaybackRange(startBeat, endBeat)
52027
+ * api.applyPlaybackRangeFromHighlight()
52028
+ * ```
52029
+ */
52030
+ applyPlaybackRangeFromHighlight() {
52031
+ if (this._selectionEnd) {
52032
+ const startTick = this._tickCache?.getBeatStart(this._selectionStart.beat) ??
52033
+ this._selectionStart.beat.absolutePlaybackStart;
52034
+ const endTick = this._tickCache?.getBeatStart(this._selectionEnd.beat) ??
52035
+ this._selectionEnd.beat.absolutePlaybackStart;
52036
+ if (endTick < startTick) {
52037
+ const t = this._selectionStart;
52038
+ this._selectionStart = this._selectionEnd;
52039
+ this._selectionEnd = t;
52040
+ }
52041
+ }
52042
+ if (this._selectionStart && this._tickCache) {
52043
+ // get the start and stop ticks (which consider properly repeats)
52044
+ const tickCache = this._tickCache;
52045
+ const realMasterBarStart = tickCache.getMasterBarStart(this._selectionStart.beat.voice.bar.masterBar);
52046
+ // move to selection start
52047
+ this._currentBeat = null; // reset current beat so it is updating the cursor
52048
+ if (this._player.state === PlayerState.Paused) {
52049
+ this._cursorUpdateTick(this._tickCache.getBeatStart(this._selectionStart.beat), false, 1);
52050
+ }
52051
+ this.tickPosition = realMasterBarStart + this._selectionStart.beat.playbackStart;
52052
+ // set playback range
52053
+ if (this._selectionEnd && this._selectionStart.beat !== this._selectionEnd.beat) {
52054
+ const realMasterBarEnd = tickCache.getMasterBarStart(this._selectionEnd.beat.voice.bar.masterBar);
52055
+ const range = new PlaybackRange();
52056
+ range.startTick = realMasterBarStart + this._selectionStart.beat.playbackStart;
52057
+ range.endTick =
52058
+ realMasterBarEnd +
52059
+ this._selectionEnd.beat.playbackStart +
52060
+ this._selectionEnd.beat.playbackDuration -
52061
+ 50;
52062
+ this.playbackRange = range;
52063
+ }
52064
+ else {
52065
+ this._selectionStart = undefined;
52066
+ this.playbackRange = null;
52067
+ this._cursorSelectRange(this._selectionStart, this._selectionEnd);
52068
+ }
52069
+ }
52070
+ }
52071
+ /**
52072
+ * Clears the highlight markers marking the currently selected playback range.
52073
+ *
52074
+ * @remarks
52075
+ * Unlike actually setting {@link playbackRange} this method only clears the selection markers without actually
52076
+ * changing the playback range. This method can be used when building custom selection systems (e.g. having draggable handles).
52077
+ *
52078
+ * @category Methods - Player
52079
+ * @since 1.8.0
52080
+ *
52081
+ * @example
52082
+ * JavaScript
52083
+ * ```js
52084
+ * const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab'));
52085
+ * api.clearPlaybackRangeHighlight();
52086
+ * ```
52087
+ *
52088
+ * @example
52089
+ * C#
52090
+ * ```cs
52091
+ * var api = new AlphaTabApi<MyControl>(...);
52092
+ * api.clearPlaybackRangeHighlight();
52093
+ * ```
52094
+ *
52095
+ * @example
52096
+ * Android
52097
+ * ```kotlin
52098
+ * val api = AlphaTabApi<MyControl>(...)
52099
+ * api.clearPlaybackRangeHighlight()
52100
+ * ```
52101
+ */
52102
+ clearPlaybackRangeHighlight() {
52103
+ this._cursorSelectRange(undefined, undefined);
52104
+ }
52105
+ /**
52106
+ * This event is fired the shown highlights for the selected playback range changes.
52107
+ *
52108
+ * @remarks
52109
+ * This event is fired already during selection and not only when the selection is completed.
52110
+ * This event can be used to place additional custom selection markers (like drag handles).
52111
+ *
52112
+ * @eventProperty
52113
+ * @category Events - Player
52114
+ * @since 1.8.0
52115
+ *
52116
+ * @example
52117
+ * JavaScript
52118
+ * ```js
52119
+ * const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab'));
52120
+ * api.playbackRangeHighlightChanged.on(e => {
52121
+ * updateSelectionHandles(e);
52122
+ * });
52123
+ * ```
52124
+ *
52125
+ * @example
52126
+ * C#
52127
+ * ```cs
52128
+ * var api = new AlphaTabApi<MyControl>(...);
52129
+ * api.PlaybackRangeHighlightChanged.On(e =>
52130
+ * {
52131
+ * UpdateSelectionHandles(e);
52132
+ * });
52133
+ * ```
52134
+ *
52135
+ * @example
52136
+ * Android
52137
+ * ```kotlin
52138
+ * val api = AlphaTabApi<MyControl>(...)
52139
+ * api.playbackRangeHighlightChanged.on { e ->
52140
+ * updateSelectionHandles(e)
52141
+ * }
52142
+ * ```
52143
+ *
52144
+ */
52145
+ playbackRangeHighlightChanged = new EventEmitterOfT();
51985
52146
  _cursorSelectRange(startBeat, endBeat) {
51986
52147
  const cache = this._renderer.boundsLookup;
51987
52148
  if (!cache) {
52149
+ this.playbackRangeHighlightChanged.trigger({});
51988
52150
  return;
51989
52151
  }
51990
52152
  const selectionWrapper = this._selectionWrapper;
51991
52153
  if (!selectionWrapper) {
52154
+ this.playbackRangeHighlightChanged.trigger({});
51992
52155
  return;
51993
52156
  }
51994
52157
  selectionWrapper.clear();
51995
52158
  if (!startBeat || !endBeat || startBeat.beat === endBeat.beat) {
52159
+ this.playbackRangeHighlightChanged.trigger({});
51996
52160
  return;
51997
52161
  }
51998
52162
  if (!startBeat.bounds) {
51999
- startBeat.bounds = cache.findBeat(startBeat.beat);
52163
+ startBeat.bounds = cache.findBeat(startBeat.beat) ?? undefined;
52000
52164
  }
52001
52165
  if (!endBeat.bounds) {
52002
- endBeat.bounds = cache.findBeat(endBeat.beat);
52166
+ endBeat.bounds = cache.findBeat(endBeat.beat) ?? undefined;
52003
52167
  }
52004
52168
  const startTick = this._tickCache?.getBeatStart(startBeat.beat) ?? startBeat.beat.absolutePlaybackStart;
52005
52169
  const endTick = this._tickCache?.getBeatStart(endBeat.beat) ?? endBeat.beat.absolutePlaybackStart;
@@ -52008,7 +52172,17 @@ class AlphaTabApiBase {
52008
52172
  startBeat = endBeat;
52009
52173
  endBeat = t;
52010
52174
  }
52011
- const startX = startBeat.bounds.realBounds.x;
52175
+ const eventArgs = {
52176
+ startBeat: startBeat.beat,
52177
+ startBeatBounds: startBeat.bounds,
52178
+ endBeat: endBeat.beat,
52179
+ endBeatBounds: endBeat.bounds,
52180
+ highlightBlocks: []
52181
+ };
52182
+ let startX = startBeat.bounds.realBounds.x;
52183
+ if (startBeat.beat.index === 0) {
52184
+ startX = startBeat.bounds.barBounds.masterBarBounds.realBounds.x;
52185
+ }
52012
52186
  let endX = endBeat.bounds.realBounds.x + endBeat.bounds.realBounds.w;
52013
52187
  if (endBeat.beat.index === endBeat.beat.voice.beats.length - 1) {
52014
52188
  endX =
@@ -52025,18 +52199,24 @@ class AlphaTabApiBase {
52025
52199
  const staffEndX = startBeat.bounds.barBounds.masterBarBounds.staffSystemBounds.visualBounds.x +
52026
52200
  startBeat.bounds.barBounds.masterBarBounds.staffSystemBounds.visualBounds.w;
52027
52201
  const startSelection = this.uiFacade.createSelectionElement();
52028
- startSelection.setBounds(startX, startBeat.bounds.barBounds.masterBarBounds.visualBounds.y, staffEndX - startX, startBeat.bounds.barBounds.masterBarBounds.visualBounds.h);
52202
+ const startSelectionBounds = new Bounds(startX, startBeat.bounds.barBounds.masterBarBounds.visualBounds.y, staffEndX - startX, startBeat.bounds.barBounds.masterBarBounds.visualBounds.h);
52203
+ startSelection.setBounds(startSelectionBounds.x, startSelectionBounds.y, startSelectionBounds.w, startSelectionBounds.h);
52204
+ eventArgs.highlightBlocks.push(startSelectionBounds);
52029
52205
  selectionWrapper.appendChild(startSelection);
52030
52206
  const staffStartIndex = startBeat.bounds.barBounds.masterBarBounds.staffSystemBounds.index + 1;
52031
52207
  const staffEndIndex = endBeat.bounds.barBounds.masterBarBounds.staffSystemBounds.index;
52032
52208
  for (let staffIndex = staffStartIndex; staffIndex < staffEndIndex; staffIndex++) {
52033
52209
  const staffBounds = cache.staffSystems[staffIndex];
52034
52210
  const middleSelection = this.uiFacade.createSelectionElement();
52035
- middleSelection.setBounds(staffStartX, staffBounds.visualBounds.y, staffEndX - staffStartX, staffBounds.visualBounds.h);
52211
+ const middleSelectionBounds = new Bounds(staffStartX, staffBounds.visualBounds.y, staffEndX - staffStartX, staffBounds.visualBounds.h);
52212
+ eventArgs.highlightBlocks.push(middleSelectionBounds);
52213
+ middleSelection.setBounds(middleSelectionBounds.x, middleSelectionBounds.y, middleSelectionBounds.w, middleSelectionBounds.h);
52036
52214
  selectionWrapper.appendChild(middleSelection);
52037
52215
  }
52038
52216
  const endSelection = this.uiFacade.createSelectionElement();
52039
- endSelection.setBounds(staffStartX, endBeat.bounds.barBounds.masterBarBounds.visualBounds.y, endX - staffStartX, endBeat.bounds.barBounds.masterBarBounds.visualBounds.h);
52217
+ const endSelectionBounds = new Bounds(staffStartX, endBeat.bounds.barBounds.masterBarBounds.visualBounds.y, endX - staffStartX, endBeat.bounds.barBounds.masterBarBounds.visualBounds.h);
52218
+ eventArgs.highlightBlocks.push(endSelectionBounds);
52219
+ endSelection.setBounds(endSelectionBounds.x, endSelectionBounds.y, endSelectionBounds.w, endSelectionBounds.h);
52040
52220
  selectionWrapper.appendChild(endSelection);
52041
52221
  }
52042
52222
  else {
@@ -52045,6 +52225,7 @@ class AlphaTabApiBase {
52045
52225
  selection.setBounds(startX, startBeat.bounds.barBounds.masterBarBounds.visualBounds.y, endX - startX, startBeat.bounds.barBounds.masterBarBounds.visualBounds.h);
52046
52226
  selectionWrapper.appendChild(selection);
52047
52227
  }
52228
+ this.playbackRangeHighlightChanged.trigger(eventArgs);
52048
52229
  }
52049
52230
  /**
52050
52231
  * This event is fired whenever a new song is loaded.
@@ -1745,8 +1745,8 @@ export declare class AlphaTabApiBase<TSettings> {
1745
1745
  private _onActiveBeatsChanged;
1746
1746
  private _isBeatMouseDown;
1747
1747
  private _isNoteMouseDown;
1748
- private _selectionStart;
1749
- private _selectionEnd;
1748
+ private _selectionStart?;
1749
+ private _selectionEnd?;
1750
1750
  /**
1751
1751
  * This event is fired whenever a the user presses the mouse button on a beat.
1752
1752
  * @eventProperty
@@ -1990,6 +1990,163 @@ export declare class AlphaTabApiBase<TSettings> {
1990
1990
  private _onNoteMouseUp;
1991
1991
  private _updateSelectionCursor;
1992
1992
  private _setupClickHandling;
1993
+ /**
1994
+ * Places the highlight markers at the specified start and end-beat range.
1995
+ * @param startBeat The start beat where the selection should start
1996
+ * @param endBeat The end beat where the selection should end.
1997
+ *
1998
+ * @remarks
1999
+ * Unlike actually setting {@link playbackRange} this method only places the selection markers without actually
2000
+ * changing the playback range. This method can be used when building custom selection systems (e.g. having draggable handles).
2001
+ *
2002
+ * @category Methods - Player
2003
+ * @since 1.8.0
2004
+ *
2005
+ * @example
2006
+ * JavaScript
2007
+ * ```js
2008
+ * const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab'));
2009
+ * const startBeat = api.score.tracks[0].staves[0].bars[0].voices[0].beats[0];
2010
+ * const endBeat = api.score.tracks[0].staves[0].bars[3].voices[0].beats[0];
2011
+ * api.highlightPlaybackRange(startBeat, endBeat);
2012
+ * ```
2013
+ *
2014
+ * @example
2015
+ * C#
2016
+ * ```cs
2017
+ * var api = new AlphaTabApi<MyControl>(...);
2018
+ * api.ChangeTrackVolume(new Track[] { api.Score.Tracks[0], api.Score.Tracks[1] }, 1.5);
2019
+ * api.ChangeTrackVolume(new Track[] { api.Score.Tracks[2] }, 0.5);
2020
+ * var startBeat = api.Score.Tracks[0].Staves[0].Bars[0].Voices[0].Beats[0];
2021
+ * var endBeat = api.Score.Tracks[0].Staves[0].Bars[3].Voices[0].Beats[0];
2022
+ * api.HighlightPlaybackRange(startBeat, endBeat);
2023
+ * ```
2024
+ *
2025
+ * @example
2026
+ * Android
2027
+ * ```kotlin
2028
+ * val api = AlphaTabApi<MyControl>(...)
2029
+ * val startBeat = api.score.tracks[0].staves[0].bars[0].voices[0].beats[0]
2030
+ * val endBeat = api.score.tracks[0].staves[0].bars[3].voices[0].beats[0]
2031
+ * api.highlightPlaybackRange(startBeat, endBeat)
2032
+ * ```
2033
+ */
2034
+ highlightPlaybackRange(startBeat: Beat, endBeat: Beat): void;
2035
+ /**
2036
+ * Applies the playback range from the currently highlighted range.
2037
+ *
2038
+ * @remarks
2039
+ * This method can be used when building custom selection systems (e.g. having draggable handles).
2040
+ *
2041
+ * @category Methods - Player
2042
+ * @since 1.8.0
2043
+ *
2044
+ * @example
2045
+ * JavaScript
2046
+ * ```js
2047
+ * const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab'));
2048
+ * const startBeat = api.score.tracks[0].staves[0].bars[0].voices[0].beats[0];
2049
+ * const endBeat = api.score.tracks[0].staves[0].bars[3].voices[0].beats[0];
2050
+ * api.highlightPlaybackRange(startBeat, endBeat);
2051
+ * api.applyPlaybackRangeFromHighlight();
2052
+ * ```
2053
+ *
2054
+ * @example
2055
+ * C#
2056
+ * ```cs
2057
+ * var api = new AlphaTabApi<MyControl>(...);
2058
+ * api.ChangeTrackVolume(new Track[] { api.Score.Tracks[0], api.Score.Tracks[1] }, 1.5);
2059
+ * api.ChangeTrackVolume(new Track[] { api.Score.Tracks[2] }, 0.5);
2060
+ * var startBeat = api.Score.Tracks[0].Staves[0].Bars[0].Voices[0].Beats[0];
2061
+ * var endBeat = api.Score.Tracks[0].Staves[0].Bars[3].Voices[0].Beats[0];
2062
+ * api.HighlightPlaybackRange(startBeat, endBeat);
2063
+ * api.ApplyPlaybackRangeFromHighlight();
2064
+ * ```
2065
+ *
2066
+ * @example
2067
+ * Android
2068
+ * ```kotlin
2069
+ * val api = AlphaTabApi<MyControl>(...)
2070
+ * val startBeat = api.score.tracks[0].staves[0].bars[0].voices[0].beats[0]
2071
+ * val endBeat = api.score.tracks[0].staves[0].bars[3].voices[0].beats[0]
2072
+ * api.highlightPlaybackRange(startBeat, endBeat)
2073
+ * api.applyPlaybackRangeFromHighlight()
2074
+ * ```
2075
+ */
2076
+ applyPlaybackRangeFromHighlight(): void;
2077
+ /**
2078
+ * Clears the highlight markers marking the currently selected playback range.
2079
+ *
2080
+ * @remarks
2081
+ * Unlike actually setting {@link playbackRange} this method only clears the selection markers without actually
2082
+ * changing the playback range. This method can be used when building custom selection systems (e.g. having draggable handles).
2083
+ *
2084
+ * @category Methods - Player
2085
+ * @since 1.8.0
2086
+ *
2087
+ * @example
2088
+ * JavaScript
2089
+ * ```js
2090
+ * const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab'));
2091
+ * api.clearPlaybackRangeHighlight();
2092
+ * ```
2093
+ *
2094
+ * @example
2095
+ * C#
2096
+ * ```cs
2097
+ * var api = new AlphaTabApi<MyControl>(...);
2098
+ * api.clearPlaybackRangeHighlight();
2099
+ * ```
2100
+ *
2101
+ * @example
2102
+ * Android
2103
+ * ```kotlin
2104
+ * val api = AlphaTabApi<MyControl>(...)
2105
+ * api.clearPlaybackRangeHighlight()
2106
+ * ```
2107
+ */
2108
+ clearPlaybackRangeHighlight(): void;
2109
+ /**
2110
+ * This event is fired the shown highlights for the selected playback range changes.
2111
+ *
2112
+ * @remarks
2113
+ * This event is fired already during selection and not only when the selection is completed.
2114
+ * This event can be used to place additional custom selection markers (like drag handles).
2115
+ *
2116
+ * @eventProperty
2117
+ * @category Events - Player
2118
+ * @since 1.8.0
2119
+ *
2120
+ * @example
2121
+ * JavaScript
2122
+ * ```js
2123
+ * const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab'));
2124
+ * api.playbackRangeHighlightChanged.on(e => {
2125
+ * updateSelectionHandles(e);
2126
+ * });
2127
+ * ```
2128
+ *
2129
+ * @example
2130
+ * C#
2131
+ * ```cs
2132
+ * var api = new AlphaTabApi<MyControl>(...);
2133
+ * api.PlaybackRangeHighlightChanged.On(e =>
2134
+ * {
2135
+ * UpdateSelectionHandles(e);
2136
+ * });
2137
+ * ```
2138
+ *
2139
+ * @example
2140
+ * Android
2141
+ * ```kotlin
2142
+ * val api = AlphaTabApi<MyControl>(...)
2143
+ * api.playbackRangeHighlightChanged.on { e ->
2144
+ * updateSelectionHandles(e)
2145
+ * }
2146
+ * ```
2147
+ *
2148
+ */
2149
+ readonly playbackRangeHighlightChanged: IEventEmitterOfT<PlaybackHighlightChangeEventArgs>;
1993
2150
  private _cursorSelectRange;
1994
2151
  /**
1995
2152
  * This event is fired whenever a new song is loaded.
@@ -5230,6 +5387,7 @@ declare class Bounds {
5230
5387
  */
5231
5388
  h: number;
5232
5389
  scaleWith(scale: number): void;
5390
+ constructor(x?: number, y?: number, w?: number, h?: number);
5233
5391
  }
5234
5392
 
5235
5393
  /**
@@ -12803,6 +12961,35 @@ export declare namespace platform {
12803
12961
  }
12804
12962
  }
12805
12963
 
12964
+ /**
12965
+ * Holds information about the highlights shown for the playback range.
12966
+ * @public
12967
+ * @record
12968
+ */
12969
+ export declare interface PlaybackHighlightChangeEventArgs {
12970
+ /**
12971
+ * The beat where the selection starts. undefined if there is no selection.
12972
+ */
12973
+ startBeat?: Beat;
12974
+ /**
12975
+ * The bounds of the start beat to determine its location and size.
12976
+ */
12977
+ startBeatBounds?: BeatBounds;
12978
+ /**
12979
+ * The beat where the selection ends. undefined if there is no selection.
12980
+ */
12981
+ endBeat?: Beat;
12982
+ /**
12983
+ * The bounds of the end beat to determine its location and size.
12984
+ */
12985
+ endBeatBounds?: BeatBounds;
12986
+ /**
12987
+ * A list of the individual rectangular areas where highlight blocks are placed.
12988
+ * If a selection spans multiple lines this array will hold all items.
12989
+ */
12990
+ highlightBlocks?: Bounds[];
12991
+ }
12992
+
12806
12993
  /**
12807
12994
  * This public class stores the midi specific information of a track needed
12808
12995
  * for playback.