@coderline/alphatab 1.9.0-alpha.1860 → 1.9.0-alpha.1861

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.9.0-alpha.1860 (develop, build 1860)
2
+ * alphaTab v1.9.0-alpha.1861 (develop, build 1861)
3
3
  *
4
4
  * Copyright © 2026, Daniel Kuschny and Contributors, All rights reserved.
5
5
  *
@@ -186,9 +186,9 @@ class AlphaTabError extends Error {
186
186
  * @internal
187
187
  */
188
188
  class VersionInfo {
189
- static version = "1.9.0-alpha.1860";
190
- static date = "2026-07-10T14:22:26.590Z";
191
- static commit = "1efc2ecc10ca13f2bfbec400427822dc4bdfc160";
189
+ static version = "1.9.0-alpha.1861";
190
+ static date = "2026-07-11T03:34:14.452Z";
191
+ static commit = "18845390986e826fff8ae285ee3630080dbd6653";
192
192
  static print(print) {
193
193
  print(`alphaTab ${VersionInfo.version}`);
194
194
  print(`commit: ${VersionInfo.commit}`);
@@ -29197,11 +29197,45 @@ class PlayerSettings {
29197
29197
  * @since 0.9.7
29198
29198
  * @defaultValue `true`
29199
29199
  * @category Player
29200
+ * @json_read_only
29200
29201
  * @remarks
29201
29202
  * This setting configures whether alphaTab provides the default user interaction features like selection of the playback range and "seek on click".
29202
29203
  * By default users can select the desired playback range with the mouse and also jump to individual beats by click. This behavior can be contolled with this setting.
29204
+ * @deprecated Use {@link enableSeekToClick} and {@link enablePlaybackRangeSelection} individually
29205
+ */
29206
+ get enableUserInteraction() {
29207
+ return this.enableSeekToClick || this.enablePlaybackRangeSelection;
29208
+ }
29209
+ /**
29210
+ * @deprecated Use {@link enableSeekToClick} and {@link enablePlaybackRangeSelection} individually
29211
+ */
29212
+ set enableUserInteraction(value) {
29213
+ this.enableSeekToClick = value;
29214
+ this.enablePlaybackRangeSelection = value;
29215
+ this.resetPlaybackRangeOnClick = value;
29216
+ }
29217
+ /**
29218
+ * Whether the a click on the music sheet triggers a player seek to the note/beat at the
29219
+ * clicked location.
29220
+ * @since 1.9.0
29221
+ * @defaultValue `true`
29222
+ * @category Player
29223
+ */
29224
+ enableSeekToClick = true;
29225
+ /**
29226
+ * Whether user click and drag results in a selection defining the playback range.
29227
+ * @since 1.9.0
29228
+ * @defaultValue `true`
29229
+ * @category Player
29203
29230
  */
29204
- enableUserInteraction = true;
29231
+ enablePlaybackRangeSelection = true;
29232
+ /**
29233
+ * Whether a simple click (no range drag) should reset the current playback range.
29234
+ * @since 1.9.0
29235
+ * @defaultValue `true`
29236
+ * @category Player
29237
+ */
29238
+ resetPlaybackRangeOnClick = true;
29205
29239
  /**
29206
29240
  * The X-offset to add when scrolling.
29207
29241
  * @since 0.9.6
@@ -30358,7 +30392,9 @@ class PlayerSettingsSerializer {
30358
30392
  o.set("enablecursor", obj.enableCursor);
30359
30393
  o.set("enableanimatedbeatcursor", obj.enableAnimatedBeatCursor);
30360
30394
  o.set("enableelementhighlighting", obj.enableElementHighlighting);
30361
- o.set("enableuserinteraction", obj.enableUserInteraction);
30395
+ o.set("enableseektoclick", obj.enableSeekToClick);
30396
+ o.set("enableplaybackrangeselection", obj.enablePlaybackRangeSelection);
30397
+ o.set("resetplaybackrangeonclick", obj.resetPlaybackRangeOnClick);
30362
30398
  o.set("scrolloffsetx", obj.scrollOffsetX);
30363
30399
  o.set("scrolloffsety", obj.scrollOffsetY);
30364
30400
  o.set("scrollmode", obj.scrollMode);
@@ -30401,6 +30437,15 @@ class PlayerSettingsSerializer {
30401
30437
  case "enableuserinteraction":
30402
30438
  obj.enableUserInteraction = v;
30403
30439
  return true;
30440
+ case "enableseektoclick":
30441
+ obj.enableSeekToClick = v;
30442
+ return true;
30443
+ case "enableplaybackrangeselection":
30444
+ obj.enablePlaybackRangeSelection = v;
30445
+ return true;
30446
+ case "resetplaybackrangeonclick":
30447
+ obj.resetPlaybackRangeOnClick = v;
30448
+ return true;
30404
30449
  case "scrolloffsetx":
30405
30450
  obj.scrollOffsetX = v;
30406
30451
  return true;
@@ -45399,6 +45444,16 @@ class BeatContainerGlyphBase extends Glyph {
45399
45444
  scaleToWidth(beatWidth) {
45400
45445
  this.width = beatWidth;
45401
45446
  }
45447
+ /**
45448
+ * Repositions this beat so its {@link onTimeX} anchor lands at `target`, used for the
45449
+ * centered full-bar note/rest (see {@link BarLayoutingInfo.isCenteredFullBar}). The default
45450
+ * shifts the whole container, matching the regular (non-centered) positioning formula.
45451
+ * {@link BeatContainerGlyph} overrides this to shift only its ink, keeping `x`/`width`
45452
+ * spanning the full bar so bounds lookups and skyline emission stay correct.
45453
+ */
45454
+ applyCenterOffset(target) {
45455
+ this.x = target - this.onTimeX;
45456
+ }
45402
45457
  }
45403
45458
  /**
45404
45459
  * @internal
@@ -45502,13 +45557,28 @@ class BeatContainerGlyph extends BeatContainerGlyphBase {
45502
45557
  this.preNotes.renderer = this.renderer;
45503
45558
  this.preNotes.container = this;
45504
45559
  this.preNotes.doLayout();
45505
- this.onNotes.x = this.preNotes.x + this.preNotes.width;
45560
+ this._layoutOnsetX();
45506
45561
  this.onNotes.renderer = this.renderer;
45507
45562
  this.onNotes.container = this;
45508
45563
  this.onNotes.doLayout();
45509
45564
  this.createBeatTies();
45510
45565
  this.updateWidth();
45511
45566
  }
45567
+ /**
45568
+ * Resets `preNotes.x`/`onNotes.x` to their natural (un-centered) baseline.
45569
+ * Shared by {@link doLayout} and {@link applyCenterOffset} so the latter can be called
45570
+ * repeatedly (once per `_scaleToForce` pass) without compounding a previous offset.
45571
+ */
45572
+ _layoutOnsetX() {
45573
+ this.preNotes.x = 0;
45574
+ this.onNotes.x = this.preNotes.x + this.preNotes.width;
45575
+ }
45576
+ applyCenterOffset(target) {
45577
+ this._layoutOnsetX();
45578
+ const offset = target - this.onTimeX;
45579
+ this.preNotes.x = offset;
45580
+ this.onNotes.x = this.preNotes.x + this.preNotes.width;
45581
+ }
45512
45582
  createBeatTies() {
45513
45583
  let i = this.beat.notes.length - 1;
45514
45584
  while (i >= 0) this.createTies(this.beat.notes[i--]);
@@ -48598,7 +48668,7 @@ class AlphaTabApiBase {
48598
48668
  }
48599
48669
  _onBeatMouseDown(originalEvent, beat) {
48600
48670
  if (this._isDestroyed) return;
48601
- if (this._hasCursor && this.settings.player.enableUserInteraction) {
48671
+ if (this._hasCursor && this.settings.player.enablePlaybackRangeSelection) {
48602
48672
  this._selectionStart = { beat };
48603
48673
  this._selectionEnd = void 0;
48604
48674
  }
@@ -48614,10 +48684,12 @@ class AlphaTabApiBase {
48614
48684
  }
48615
48685
  _onBeatMouseMove(originalEvent, beat) {
48616
48686
  if (this._isDestroyed) return;
48617
- if (this.settings.player.enableUserInteraction) {
48687
+ if (this.settings.player.enablePlaybackRangeSelection) {
48618
48688
  if (!this._selectionEnd || this._selectionEnd.beat !== beat) {
48619
- this._selectionEnd = { beat };
48620
- this._cursorSelectRange(this._selectionStart, this._selectionEnd);
48689
+ if (this._selectionStart?.beat !== beat) {
48690
+ this._selectionEnd = { beat };
48691
+ this._cursorSelectRange(this._selectionStart, this._selectionEnd);
48692
+ }
48621
48693
  }
48622
48694
  }
48623
48695
  this.beatMouseMove.trigger(beat);
@@ -48630,11 +48702,30 @@ class AlphaTabApiBase {
48630
48702
  }
48631
48703
  _onBeatMouseUp(originalEvent, beat) {
48632
48704
  if (this._isDestroyed) return;
48633
- if (this._hasCursor && this.settings.player.enableUserInteraction) this.applyPlaybackRangeFromHighlight();
48705
+ if (this._hasCursor) {
48706
+ let shouldSeekToBeat = beat && this.settings.player.enableSeekToClick;
48707
+ if (this.settings.player.enablePlaybackRangeSelection) {
48708
+ if (this._internalApplyPlaybackRangeFromHighlight()) shouldSeekToBeat = false;
48709
+ }
48710
+ if (shouldSeekToBeat) this._seekToBeat(beat);
48711
+ }
48634
48712
  this.beatMouseUp.trigger(beat);
48635
48713
  this.uiFacade.triggerEvent(this.container, "beatMouseUp", beat, originalEvent);
48636
48714
  this._isBeatMouseDown = false;
48637
48715
  }
48716
+ _seekToBeat(beat) {
48717
+ const tickCache = this._tickCache;
48718
+ if (!tickCache) return;
48719
+ this._currentBeat = null;
48720
+ let beatTick = tickCache.getMasterBarStart(beat.voice.bar.masterBar) + (tickCache.getRelativeBeatPlaybackRange(beat)?.startTick ?? beat.playbackStart);
48721
+ const playbackRange = this.playbackRange;
48722
+ if (playbackRange) {
48723
+ if (beatTick < playbackRange.startTick) beatTick = playbackRange.startTick;
48724
+ else if (beatTick > playbackRange.endTick) beatTick = playbackRange.endTick;
48725
+ }
48726
+ if (this._player.state === PlayerState.Paused) this._cursorUpdateTick(beatTick, false, 1);
48727
+ this.tickPosition = beatTick;
48728
+ }
48638
48729
  _onNoteMouseUp(originalEvent, note) {
48639
48730
  if (this._isDestroyed) return;
48640
48731
  this.noteMouseUp.trigger(note);
@@ -48656,7 +48747,7 @@ class AlphaTabApiBase {
48656
48747
  _setupClickHandling() {
48657
48748
  this.canvasElement.mouseDown.on((e) => {
48658
48749
  if (!e.isLeftMouseButton) return;
48659
- if (this.settings.player.enableUserInteraction) e.preventDefault();
48750
+ if (this.settings.player.enablePlaybackRangeSelection || this.settings.player.enableSeekToClick) e.preventDefault();
48660
48751
  const relX = e.getX(this.canvasElement);
48661
48752
  const relY = e.getY(this.canvasElement);
48662
48753
  const beat = this._renderer.boundsLookup?.getBeatAtPos(relX, relY) ?? null;
@@ -48683,7 +48774,7 @@ class AlphaTabApiBase {
48683
48774
  });
48684
48775
  this.canvasElement.mouseUp.on((e) => {
48685
48776
  if (!this._isBeatMouseDown) return;
48686
- if (this.settings.player.enableUserInteraction) e.preventDefault();
48777
+ if (this.settings.player.enablePlaybackRangeSelection || this.settings.player.enableSeekToClick) e.preventDefault();
48687
48778
  const relX = e.getX(this.canvasElement);
48688
48779
  const relY = e.getY(this.canvasElement);
48689
48780
  const beat = this._renderer.boundsLookup?.getBeatAtPos(relX, relY) ?? null;
@@ -48694,7 +48785,7 @@ class AlphaTabApiBase {
48694
48785
  } else this._onNoteMouseUp(e, null);
48695
48786
  });
48696
48787
  this._renderer.postRenderFinished.on(() => {
48697
- if (!this._selectionStart || !this._hasCursor || !this.settings.player.enableUserInteraction) return;
48788
+ if (!this._selectionStart || !this._hasCursor || !this.settings.player.enablePlaybackRangeSelection) return;
48698
48789
  this._cursorSelectRange(this._selectionStart, this._selectionEnd);
48699
48790
  });
48700
48791
  }
@@ -48786,6 +48877,9 @@ class AlphaTabApiBase {
48786
48877
  * ```
48787
48878
  */
48788
48879
  applyPlaybackRangeFromHighlight() {
48880
+ this._internalApplyPlaybackRangeFromHighlight();
48881
+ }
48882
+ _internalApplyPlaybackRangeFromHighlight() {
48789
48883
  if (this._selectionEnd) {
48790
48884
  const startTick = this._tickCache?.getBeatStart(this._selectionStart.beat) ?? this._selectionStart.beat.absolutePlaybackStart;
48791
48885
  if ((this._tickCache?.getBeatStart(this._selectionEnd.beat) ?? this._selectionEnd.beat.absolutePlaybackStart) < startTick) {
@@ -48793,27 +48887,32 @@ class AlphaTabApiBase {
48793
48887
  this._selectionStart = this._selectionEnd;
48794
48888
  this._selectionEnd = t;
48795
48889
  }
48796
- }
48890
+ } else if (!this.settings.player.resetPlaybackRangeOnClick) return false;
48797
48891
  if (this._selectionStart && this._tickCache) {
48798
48892
  const tickCache = this._tickCache;
48799
48893
  const realStartMasterBarStart = tickCache.getMasterBarStart(this._selectionStart.beat.voice.bar.masterBar);
48800
48894
  const startBeatPlaybackStart = tickCache.getRelativeBeatPlaybackRange(this._selectionStart.beat)?.startTick ?? this._selectionStart.beat.playbackStart;
48801
- this._currentBeat = null;
48802
- if (this._player.state === PlayerState.Paused) this._cursorUpdateTick(realStartMasterBarStart + startBeatPlaybackStart, false, 1);
48803
- this.tickPosition = realStartMasterBarStart + startBeatPlaybackStart;
48895
+ let seekToStart = this.settings.player.enableSeekToClick;
48804
48896
  if (this._selectionEnd && this._selectionStart.beat !== this._selectionEnd.beat) {
48897
+ seekToStart = true;
48805
48898
  const realEndMasterBarStart = tickCache.getMasterBarStart(this._selectionEnd.beat.voice.bar.masterBar);
48806
48899
  const endBeatPlaybackEnd = tickCache.getRelativeBeatPlaybackRange(this._selectionEnd.beat)?.endTick ?? this._selectionEnd.beat.playbackStart + this._selectionEnd.beat.playbackDuration;
48807
48900
  const range = new PlaybackRange();
48808
48901
  range.startTick = realStartMasterBarStart + startBeatPlaybackStart;
48809
48902
  range.endTick = realEndMasterBarStart + endBeatPlaybackEnd - 50;
48810
48903
  this.playbackRange = range;
48811
- } else {
48904
+ } else if (this.settings.player.resetPlaybackRangeOnClick) {
48812
48905
  this._selectionStart = void 0;
48813
48906
  this.playbackRange = null;
48814
48907
  this._cursorSelectRange(this._selectionStart, this._selectionEnd);
48815
48908
  }
48909
+ if (seekToStart) {
48910
+ this._currentBeat = null;
48911
+ if (this._player.state === PlayerState.Paused) this._cursorUpdateTick(realStartMasterBarStart + startBeatPlaybackStart, false, 1);
48912
+ this.tickPosition = realStartMasterBarStart + startBeatPlaybackStart;
48913
+ }
48816
48914
  }
48915
+ return true;
48817
48916
  }
48818
48917
  /**
48819
48918
  * Clears the highlight markers marking the currently selected playback range.
@@ -50099,7 +50198,8 @@ class AlphaTabApi extends AlphaTabApiBase {
50099
50198
  settings.player.enableCursor = false;
50100
50199
  settings.player.playerMode = PlayerMode.Disabled;
50101
50200
  settings.player.enableElementHighlighting = false;
50102
- settings.player.enableUserInteraction = false;
50201
+ settings.player.enableSeekToClick = false;
50202
+ settings.player.enablePlaybackRangeSelection = false;
50103
50203
  settings.player.soundFont = null;
50104
50204
  settings.display.scale = .8;
50105
50205
  settings.display.stretchForce = .8;
@@ -50909,7 +51009,9 @@ class AlphaSynthWebWorker {
50909
51009
  }
50910
51010
  handleMessage(e) {
50911
51011
  const data = e.data;
50912
- switch (data.cmd) {
51012
+ const cmd = data.cmd;
51013
+ if (!cmd) return;
51014
+ switch (cmd) {
50913
51015
  case "alphaSynth.initialize":
50914
51016
  AlphaSynthWorkerSynthOutput.preferredSampleRate = data.sampleRate;
50915
51017
  Logger.logLevel = data.logLevel;
@@ -51003,7 +51105,7 @@ class AlphaSynthWebWorker {
51003
51105
  this._player.applyTranspositionPitches(data.transpositionPitches);
51004
51106
  break;
51005
51107
  }
51006
- if (data.cmd.startsWith("alphaSynth.exporter")) this._handleExporterMessage(e);
51108
+ if (cmd.startsWith("alphaSynth.exporter")) this._handleExporterMessage(e);
51007
51109
  }
51008
51110
  _handleExporterMessage(ev) {
51009
51111
  const data = ev.data;
@@ -54507,9 +54609,35 @@ class MultiVoiceContainerGlyph extends Glyph {
54507
54609
  const force = this.renderer.layoutingInfo.spaceToForce(width);
54508
54610
  this._scaleToForce(force, true);
54509
54611
  }
54612
+ /**
54613
+ * `true` when every voice/track/staff contributes exactly one beat, of uniform duration,
54614
+ * spanning the bar's entire duration - i.e. a single full-bar note/rest. Common engraving
54615
+ * practice centers such notes horizontally within the bar rather than anchoring them right
54616
+ * after the pre-beat content (Behind Bars, p. 41; see #2464).
54617
+ */
54618
+ _isCenteredFullBar() {
54619
+ const masterBar = this.renderer.bar.masterBar;
54620
+ const layoutingInfo = this.renderer.layoutingInfo;
54621
+ const springs = layoutingInfo.springs;
54622
+ if (springs.size !== 1 || !springs.has(masterBar.start) || layoutingInfo.allGraceRods.size > 0) return false;
54623
+ const spring = springs.get(masterBar.start);
54624
+ return spring.allDurations.size === 1 && spring.longestDuration === masterBar.calculateDuration();
54625
+ }
54510
54626
  /** `emit=false`: positioning-only path; final skyline emission runs later via {@link scaleToWidth}. */
54511
54627
  _scaleToForce(force, emit) {
54512
54628
  this.width = this.renderer.layoutingInfo.calculateVoiceWidth(force);
54629
+ if (this._isCenteredFullBar()) {
54630
+ const barNumberWidth = this.renderer.barNumberWidth;
54631
+ const target = (this.width - barNumberWidth) / 2;
54632
+ for (const beatGlyphs of this.beatGlyphs.values()) {
54633
+ const soleBeatGlyph = beatGlyphs[0];
54634
+ soleBeatGlyph.x = 0;
54635
+ soleBeatGlyph.applyCenterOffset(target);
54636
+ soleBeatGlyph.scaleToWidth(this.width);
54637
+ if (emit) this._emitBeatContainerSkyline(soleBeatGlyph);
54638
+ }
54639
+ return;
54640
+ }
54513
54641
  const positions = this.renderer.layoutingInfo.buildOnTimePositions(force);
54514
54642
  for (const beatGlyphs of this.beatGlyphs.values()) for (let i = 0, j = beatGlyphs.length; i < j; i++) {
54515
54643
  const currentBeatGlyph = beatGlyphs[i];
@@ -60831,14 +60959,22 @@ class LineBarRenderer extends BarRendererBase {
60831
60959
  calculateBeamY(h, x) {
60832
60960
  return this.calculateBeamYWithDirection(h, x, this.getBeamDirection(h));
60833
60961
  }
60962
+ barNumberGlyph;
60963
+ get barNumberWidth() {
60964
+ return this.barNumberGlyph?.width ?? 0;
60965
+ }
60834
60966
  createPreBeatGlyphs() {
60835
60967
  super.createPreBeatGlyphs();
60968
+ this.barNumberGlyph = void 0;
60836
60969
  this.addPreBeatGlyph(new BarLineGlyph(false, this.bar.staff.track.score.stylesheet.extendBarLines));
60837
60970
  this.createLinePreBeatGlyphs();
60838
60971
  let hasSpaceAfterStartGlyphs = false;
60839
60972
  if (this.index === 0) hasSpaceAfterStartGlyphs = this.createStartSpacing();
60840
- if (this.shouldCreateBarNumber()) this.addPreBeatGlyph(new BarNumberGlyph(0, this.getLineHeight(-.5), this.bar.index + 1));
60841
- else if (!hasSpaceAfterStartGlyphs) this.addPreBeatGlyph(new SpacingGlyph(0, 0, this.smuflMetrics.oneStaffSpace));
60973
+ if (this.shouldCreateBarNumber()) {
60974
+ const barNumberGlyph = new BarNumberGlyph(0, this.getLineHeight(-.5), this.bar.index + 1);
60975
+ this.barNumberGlyph = barNumberGlyph;
60976
+ this.addPreBeatGlyph(barNumberGlyph);
60977
+ } else if (!hasSpaceAfterStartGlyphs) this.addPreBeatGlyph(new SpacingGlyph(0, 0, this.smuflMetrics.oneStaffSpace));
60842
60978
  }
60843
60979
  resolveClefDisplay() {
60844
60980
  return { isVisible: false };
@@ -64430,8 +64566,11 @@ class NumberedBarRenderer extends LineBarRenderer {
64430
64566
  if (this.index === 0 || this.bar.masterBar.isRepeatStart && this.staff.isCascadePrimary) this.addPreBeatGlyph(new BarLineGlyph(false, this.bar.staff.track.score.stylesheet.extendBarLines));
64431
64567
  this.createLinePreBeatGlyphs();
64432
64568
  const hasSpaceAfterStartGlyphs = this.createStartSpacing();
64433
- if (this.shouldCreateBarNumber()) this.addPreBeatGlyph(new BarNumberGlyph(0, this.getLineHeight(-.5), this.bar.index + 1));
64434
- else if (!hasSpaceAfterStartGlyphs) this.addPreBeatGlyph(new SpacingGlyph(0, 0, this.smuflMetrics.oneStaffSpace));
64569
+ if (this.shouldCreateBarNumber()) {
64570
+ const barNumberGlyph = new BarNumberGlyph(0, this.getLineHeight(-.5), this.bar.index + 1);
64571
+ this.barNumberGlyph = barNumberGlyph;
64572
+ this.addPreBeatGlyph(barNumberGlyph);
64573
+ } else if (!hasSpaceAfterStartGlyphs) this.addPreBeatGlyph(new SpacingGlyph(0, 0, this.smuflMetrics.oneStaffSpace));
64435
64574
  }
64436
64575
  createLinePreBeatGlyphs() {
64437
64576
  const timeSignatureDisplay = this.resolveTimeSignatureDisplay();
@@ -2083,6 +2083,7 @@ export declare class AlphaTabApiBase<TSettings> {
2083
2083
  private _onBeatMouseMove;
2084
2084
  private _onNoteMouseMove;
2085
2085
  private _onBeatMouseUp;
2086
+ private _seekToBeat;
2086
2087
  private _onNoteMouseUp;
2087
2088
  private _updateSelectionCursor;
2088
2089
  private _setupClickHandling;
@@ -2170,6 +2171,7 @@ export declare class AlphaTabApiBase<TSettings> {
2170
2171
  * ```
2171
2172
  */
2172
2173
  applyPlaybackRangeFromHighlight(): void;
2174
+ private _internalApplyPlaybackRangeFromHighlight;
2173
2175
  /**
2174
2176
  * Clears the highlight markers marking the currently selected playback range.
2175
2177
  *
@@ -13996,11 +13998,39 @@ export declare class PlayerSettings {
13996
13998
  * @since 0.9.7
13997
13999
  * @defaultValue `true`
13998
14000
  * @category Player
14001
+ * @json_read_only
13999
14002
  * @remarks
14000
14003
  * This setting configures whether alphaTab provides the default user interaction features like selection of the playback range and "seek on click".
14001
14004
  * By default users can select the desired playback range with the mouse and also jump to individual beats by click. This behavior can be contolled with this setting.
14005
+ * @deprecated Use {@link enableSeekToClick} and {@link enablePlaybackRangeSelection} individually
14006
+ */
14007
+ get enableUserInteraction(): boolean;
14008
+ /**
14009
+ * @deprecated Use {@link enableSeekToClick} and {@link enablePlaybackRangeSelection} individually
14010
+ */
14011
+ set enableUserInteraction(value: boolean);
14012
+ /**
14013
+ * Whether the a click on the music sheet triggers a player seek to the note/beat at the
14014
+ * clicked location.
14015
+ * @since 1.9.0
14016
+ * @defaultValue `true`
14017
+ * @category Player
14018
+ */
14019
+ enableSeekToClick: boolean;
14020
+ /**
14021
+ * Whether user click and drag results in a selection defining the playback range.
14022
+ * @since 1.9.0
14023
+ * @defaultValue `true`
14024
+ * @category Player
14025
+ */
14026
+ enablePlaybackRangeSelection: boolean;
14027
+ /**
14028
+ * Whether a simple click (no range drag) should reset the current playback range.
14029
+ * @since 1.9.0
14030
+ * @defaultValue `true`
14031
+ * @category Player
14002
14032
  */
14003
- enableUserInteraction: boolean;
14033
+ resetPlaybackRangeOnClick: boolean;
14004
14034
  /**
14005
14035
  * The X-offset to add when scrolling.
14006
14036
  * @since 0.9.6
@@ -14268,11 +14298,35 @@ declare interface PlayerSettingsJson {
14268
14298
  * @since 0.9.7
14269
14299
  * @defaultValue `true`
14270
14300
  * @category Player
14301
+ * @json_read_only
14271
14302
  * @remarks
14272
14303
  * This setting configures whether alphaTab provides the default user interaction features like selection of the playback range and "seek on click".
14273
14304
  * By default users can select the desired playback range with the mouse and also jump to individual beats by click. This behavior can be contolled with this setting.
14305
+ * @deprecated Use {@link enableSeekToClick} and {@link enablePlaybackRangeSelection} individually
14274
14306
  */
14275
14307
  enableUserInteraction?: boolean;
14308
+ /**
14309
+ * Whether the a click on the music sheet triggers a player seek to the note/beat at the
14310
+ * clicked location.
14311
+ * @since 1.9.0
14312
+ * @defaultValue `true`
14313
+ * @category Player
14314
+ */
14315
+ enableSeekToClick?: boolean;
14316
+ /**
14317
+ * Whether user click and drag results in a selection defining the playback range.
14318
+ * @since 1.9.0
14319
+ * @defaultValue `true`
14320
+ * @category Player
14321
+ */
14322
+ enablePlaybackRangeSelection?: boolean;
14323
+ /**
14324
+ * Whether a simple click (no range drag) should reset the current playback range.
14325
+ * @since 1.9.0
14326
+ * @defaultValue `true`
14327
+ * @category Player
14328
+ */
14329
+ resetPlaybackRangeOnClick?: boolean;
14276
14330
  /**
14277
14331
  * The X-offset to add when scrolling.
14278
14332
  * @since 0.9.6