@coderline/alphatab 1.6.0-alpha.1409 → 1.6.0-alpha.1415
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.core.min.mjs +2 -2
- package/dist/alphaTab.core.mjs +249 -59
- package/dist/alphaTab.d.ts +53 -3
- package/dist/alphaTab.js +249 -59
- package/dist/alphaTab.min.js +2 -2
- package/dist/alphaTab.min.mjs +1 -1
- package/dist/alphaTab.mjs +1 -1
- package/dist/alphaTab.vite.js +1 -1
- package/dist/alphaTab.vite.mjs +1 -1
- package/dist/alphaTab.webpack.js +1 -1
- package/dist/alphaTab.webpack.mjs +1 -1
- package/dist/alphaTab.worker.min.mjs +1 -1
- package/dist/alphaTab.worker.mjs +1 -1
- package/dist/alphaTab.worklet.min.mjs +1 -1
- package/dist/alphaTab.worklet.mjs +1 -1
- package/package.json +1 -1
package/dist/alphaTab.core.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* alphaTab v1.6.0-alpha.
|
|
2
|
+
* alphaTab v1.6.0-alpha.1415 (develop, build 1415)
|
|
3
3
|
*
|
|
4
4
|
* Copyright © 2025, Daniel Kuschny and Contributors, All rights reserved.
|
|
5
5
|
*
|
|
@@ -3371,18 +3371,26 @@ class ModelUtils {
|
|
|
3371
3371
|
const lookup = new Map();
|
|
3372
3372
|
const score = tracks[0].score;
|
|
3373
3373
|
let currentIndex = startIndex;
|
|
3374
|
+
let tempo = score.tempo;
|
|
3374
3375
|
while (currentIndex <= endIndexInclusive) {
|
|
3375
3376
|
const currentGroupStartIndex = currentIndex;
|
|
3376
3377
|
let currentGroup = null;
|
|
3377
3378
|
while (currentIndex <= endIndexInclusive) {
|
|
3378
3379
|
const masterBar = score.masterBars[currentIndex];
|
|
3380
|
+
let hasTempoChange = false;
|
|
3381
|
+
for (const a of masterBar.tempoAutomations) {
|
|
3382
|
+
if (a.value !== tempo) {
|
|
3383
|
+
hasTempoChange = true;
|
|
3384
|
+
}
|
|
3385
|
+
tempo = a.value;
|
|
3386
|
+
}
|
|
3379
3387
|
// check if masterbar breaks multibar rests, it must be fully empty with no annotations
|
|
3380
3388
|
if (masterBar.alternateEndings ||
|
|
3381
3389
|
(masterBar.isRepeatStart && masterBar.index !== currentGroupStartIndex) ||
|
|
3382
3390
|
masterBar.isFreeTime ||
|
|
3383
3391
|
masterBar.isAnacrusis ||
|
|
3384
3392
|
masterBar.section !== null ||
|
|
3385
|
-
(masterBar.index !== currentGroupStartIndex &&
|
|
3393
|
+
(masterBar.index !== currentGroupStartIndex && hasTempoChange) ||
|
|
3386
3394
|
(masterBar.fermata !== null && masterBar.fermata.size > 0) ||
|
|
3387
3395
|
(masterBar.directions !== null && masterBar.directions.size > 0)) {
|
|
3388
3396
|
break;
|
|
@@ -20215,7 +20223,11 @@ class MusicXmlImporter extends ScoreImporter {
|
|
|
20215
20223
|
for (const c of element.childElements()) {
|
|
20216
20224
|
switch (c.localName) {
|
|
20217
20225
|
case 'direction-type':
|
|
20218
|
-
|
|
20226
|
+
// See https://github.com/CoderLine/alphaTab/issues/2102
|
|
20227
|
+
const type = c.firstElement;
|
|
20228
|
+
if (type) {
|
|
20229
|
+
directionTypes.push(type);
|
|
20230
|
+
}
|
|
20219
20231
|
break;
|
|
20220
20232
|
case 'offset':
|
|
20221
20233
|
offset = Number.parseFloat(c.innerText);
|
|
@@ -38596,6 +38608,93 @@ class AlphaSynthWrapper {
|
|
|
38596
38608
|
}
|
|
38597
38609
|
}
|
|
38598
38610
|
|
|
38611
|
+
/**
|
|
38612
|
+
* A {@link IScoreRenderer} implementation wrapping and underling other {@link IScoreRenderer}
|
|
38613
|
+
* allowing dynamic changing of the underlying instance without loosing aspects like the
|
|
38614
|
+
* event listeners.
|
|
38615
|
+
*/
|
|
38616
|
+
class ScoreRendererWrapper {
|
|
38617
|
+
constructor() {
|
|
38618
|
+
this._width = 0;
|
|
38619
|
+
this._score = null;
|
|
38620
|
+
this._trackIndexes = null;
|
|
38621
|
+
this.preRender = new EventEmitterOfT();
|
|
38622
|
+
this.renderFinished = new EventEmitterOfT();
|
|
38623
|
+
this.partialRenderFinished = new EventEmitterOfT();
|
|
38624
|
+
this.partialLayoutFinished = new EventEmitterOfT();
|
|
38625
|
+
this.postRenderFinished = new EventEmitter();
|
|
38626
|
+
this.error = new EventEmitterOfT();
|
|
38627
|
+
}
|
|
38628
|
+
get instance() {
|
|
38629
|
+
return this._instance;
|
|
38630
|
+
}
|
|
38631
|
+
set instance(value) {
|
|
38632
|
+
this._instance = value;
|
|
38633
|
+
// unregister all events from previous instance
|
|
38634
|
+
const unregister = this._instanceEventUnregister;
|
|
38635
|
+
if (unregister) {
|
|
38636
|
+
for (const e of unregister) {
|
|
38637
|
+
e();
|
|
38638
|
+
}
|
|
38639
|
+
}
|
|
38640
|
+
if (value) {
|
|
38641
|
+
// regsiter to events of new player and forward them to existing listeners
|
|
38642
|
+
const newUnregister = [];
|
|
38643
|
+
newUnregister.push(value.preRender.on(v => this.preRender.trigger(v)));
|
|
38644
|
+
newUnregister.push(value.renderFinished.on(v => this.renderFinished.trigger(v)));
|
|
38645
|
+
newUnregister.push(value.partialRenderFinished.on(v => this.partialRenderFinished.trigger(v)));
|
|
38646
|
+
newUnregister.push(value.partialLayoutFinished.on(v => this.partialLayoutFinished.trigger(v)));
|
|
38647
|
+
newUnregister.push(value.postRenderFinished.on(() => this.postRenderFinished.trigger()));
|
|
38648
|
+
newUnregister.push(value.error.on(v => this.error.trigger(v)));
|
|
38649
|
+
this._instanceEventUnregister = newUnregister;
|
|
38650
|
+
if (this._settings) {
|
|
38651
|
+
value.updateSettings(this._settings);
|
|
38652
|
+
}
|
|
38653
|
+
value.width = this._width;
|
|
38654
|
+
if (this._score !== null) {
|
|
38655
|
+
value.renderScore(this._score, this._trackIndexes);
|
|
38656
|
+
}
|
|
38657
|
+
}
|
|
38658
|
+
else {
|
|
38659
|
+
this._instanceEventUnregister = undefined;
|
|
38660
|
+
}
|
|
38661
|
+
}
|
|
38662
|
+
get boundsLookup() {
|
|
38663
|
+
return this._instance ? this._instance.boundsLookup : null;
|
|
38664
|
+
}
|
|
38665
|
+
get width() {
|
|
38666
|
+
return this._instance ? this._instance.width : 0;
|
|
38667
|
+
}
|
|
38668
|
+
set width(value) {
|
|
38669
|
+
this._width = value;
|
|
38670
|
+
if (this._instance) {
|
|
38671
|
+
this._instance.width = value;
|
|
38672
|
+
}
|
|
38673
|
+
}
|
|
38674
|
+
render() {
|
|
38675
|
+
this._instance?.render();
|
|
38676
|
+
}
|
|
38677
|
+
resizeRender() {
|
|
38678
|
+
this._instance?.resizeRender();
|
|
38679
|
+
}
|
|
38680
|
+
renderScore(score, trackIndexes) {
|
|
38681
|
+
this._score = score;
|
|
38682
|
+
this._trackIndexes = trackIndexes;
|
|
38683
|
+
this._instance?.renderScore(score, trackIndexes);
|
|
38684
|
+
}
|
|
38685
|
+
renderResult(resultId) {
|
|
38686
|
+
this._instance?.renderResult(resultId);
|
|
38687
|
+
}
|
|
38688
|
+
updateSettings(settings) {
|
|
38689
|
+
this._settings = settings;
|
|
38690
|
+
this._instance?.updateSettings(settings);
|
|
38691
|
+
}
|
|
38692
|
+
destroy() {
|
|
38693
|
+
this._instance?.destroy();
|
|
38694
|
+
this._instance = undefined;
|
|
38695
|
+
}
|
|
38696
|
+
}
|
|
38697
|
+
|
|
38599
38698
|
class SelectionInfo {
|
|
38600
38699
|
constructor(beat) {
|
|
38601
38700
|
this.bounds = null;
|
|
@@ -38615,6 +38714,18 @@ class AlphaTabApiBase {
|
|
|
38615
38714
|
get actualPlayerMode() {
|
|
38616
38715
|
return this._actualPlayerMode;
|
|
38617
38716
|
}
|
|
38717
|
+
/**
|
|
38718
|
+
* The score renderer used for rendering the music sheet.
|
|
38719
|
+
* @remarks
|
|
38720
|
+
* This is the low-level API responsible for the actual rendering engine.
|
|
38721
|
+
* Gets access to the underling {@link IScoreRenderer} that is used for the rendering.
|
|
38722
|
+
*
|
|
38723
|
+
* @category Properties - Core
|
|
38724
|
+
* @since 0.9.4
|
|
38725
|
+
*/
|
|
38726
|
+
get renderer() {
|
|
38727
|
+
return this._renderer;
|
|
38728
|
+
}
|
|
38618
38729
|
/**
|
|
38619
38730
|
* The score holding all information about the song being rendered
|
|
38620
38731
|
* @category Properties - Core
|
|
@@ -38693,6 +38804,7 @@ class AlphaTabApiBase {
|
|
|
38693
38804
|
this._previousTick = 0;
|
|
38694
38805
|
this._currentBeat = null;
|
|
38695
38806
|
this._currentBeatBounds = null;
|
|
38807
|
+
this._isInitialBeatCursorUpdate = true;
|
|
38696
38808
|
this._previousStateForCursor = PlayerState.Paused;
|
|
38697
38809
|
this._previousCursorCache = null;
|
|
38698
38810
|
this._lastScroll = 0;
|
|
@@ -39351,7 +39463,40 @@ class AlphaTabApiBase {
|
|
|
39351
39463
|
*/
|
|
39352
39464
|
this.midiLoaded = new EventEmitterOfT();
|
|
39353
39465
|
/**
|
|
39354
|
-
*
|
|
39466
|
+
* This event is fired when a settings update was requested.
|
|
39467
|
+
*
|
|
39468
|
+
* @eventProperty
|
|
39469
|
+
* @category Events - Core
|
|
39470
|
+
* @since 1.6.0
|
|
39471
|
+
*
|
|
39472
|
+
* @example
|
|
39473
|
+
* JavaScript
|
|
39474
|
+
* ```js
|
|
39475
|
+
* const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab'));
|
|
39476
|
+
* api.settingsUpdated.on(() => {
|
|
39477
|
+
* updateSettingsUI(api.settings);
|
|
39478
|
+
* });
|
|
39479
|
+
* ```
|
|
39480
|
+
*
|
|
39481
|
+
* @example
|
|
39482
|
+
* C#
|
|
39483
|
+
* ```cs
|
|
39484
|
+
* var api = new AlphaTabApi<MyControl>(...);
|
|
39485
|
+
* api.SettingsUpdated.On(() =>
|
|
39486
|
+
* {
|
|
39487
|
+
* UpdateSettingsUI(api.settings);
|
|
39488
|
+
* });
|
|
39489
|
+
* ```
|
|
39490
|
+
*
|
|
39491
|
+
* @example
|
|
39492
|
+
* Android
|
|
39493
|
+
* ```kotlin
|
|
39494
|
+
* val api = AlphaTabApi<MyControl>(...)
|
|
39495
|
+
* api.SettingsUpdated.on {
|
|
39496
|
+
* updateSettingsUI(api.settings)
|
|
39497
|
+
* }
|
|
39498
|
+
* ```
|
|
39499
|
+
*
|
|
39355
39500
|
*/
|
|
39356
39501
|
this.settingsUpdated = new EventEmitter();
|
|
39357
39502
|
this.uiFacade = uiFacade;
|
|
@@ -39365,46 +39510,46 @@ class AlphaTabApiBase {
|
|
|
39365
39510
|
Environment.printEnvironmentInfo(false);
|
|
39366
39511
|
this.canvasElement = uiFacade.createCanvasElement();
|
|
39367
39512
|
this.container.appendChild(this.canvasElement);
|
|
39513
|
+
this._renderer = new ScoreRendererWrapper();
|
|
39368
39514
|
if (this.settings.core.useWorkers &&
|
|
39369
39515
|
this.uiFacade.areWorkersSupported &&
|
|
39370
39516
|
Environment.getRenderEngineFactory(this.settings.core.engine).supportsWorkers) {
|
|
39371
|
-
this.
|
|
39517
|
+
this._renderer.instance = this.uiFacade.createWorkerRenderer();
|
|
39372
39518
|
}
|
|
39373
39519
|
else {
|
|
39374
|
-
this.
|
|
39520
|
+
this._renderer.instance = new ScoreRenderer(this.settings);
|
|
39375
39521
|
}
|
|
39376
39522
|
this.container.resize.on(Environment.throttle(() => {
|
|
39377
39523
|
if (this._isDestroyed) {
|
|
39378
39524
|
return;
|
|
39379
39525
|
}
|
|
39380
|
-
if (this.container.width !== this.
|
|
39526
|
+
if (this.container.width !== this._renderer.width) {
|
|
39381
39527
|
this.triggerResize();
|
|
39382
39528
|
}
|
|
39383
39529
|
}, uiFacade.resizeThrottle));
|
|
39384
39530
|
const initialResizeEventInfo = new ResizeEventArgs();
|
|
39385
|
-
initialResizeEventInfo.oldWidth = this.
|
|
39531
|
+
initialResizeEventInfo.oldWidth = this._renderer.width;
|
|
39386
39532
|
initialResizeEventInfo.newWidth = this.container.width | 0;
|
|
39387
39533
|
initialResizeEventInfo.settings = this.settings;
|
|
39388
39534
|
this.onResize(initialResizeEventInfo);
|
|
39389
|
-
this.
|
|
39390
|
-
this.
|
|
39535
|
+
this._renderer.preRender.on(this.onRenderStarted.bind(this));
|
|
39536
|
+
this._renderer.renderFinished.on(renderingResult => {
|
|
39391
39537
|
this.onRenderFinished(renderingResult);
|
|
39392
39538
|
});
|
|
39393
|
-
this.
|
|
39539
|
+
this._renderer.postRenderFinished.on(() => {
|
|
39394
39540
|
const duration = Date.now() - this._startTime;
|
|
39395
39541
|
Logger.debug('rendering', `Rendering completed in ${duration}ms`);
|
|
39396
39542
|
this.onPostRenderFinished();
|
|
39397
39543
|
});
|
|
39398
|
-
this.
|
|
39544
|
+
this._renderer.preRender.on(_ => {
|
|
39399
39545
|
this._startTime = Date.now();
|
|
39400
39546
|
});
|
|
39401
|
-
this.
|
|
39402
|
-
this.
|
|
39403
|
-
this.
|
|
39404
|
-
this.appendRenderResult(r);
|
|
39405
|
-
this.appendRenderResult(null); // marks last element
|
|
39547
|
+
this._renderer.partialLayoutFinished.on(r => this.appendRenderResult(r, false));
|
|
39548
|
+
this._renderer.partialRenderFinished.on(this.updateRenderResult.bind(this));
|
|
39549
|
+
this._renderer.renderFinished.on(r => {
|
|
39550
|
+
this.appendRenderResult(r, true);
|
|
39406
39551
|
});
|
|
39407
|
-
this.
|
|
39552
|
+
this._renderer.error.on(this.onError.bind(this));
|
|
39408
39553
|
this.setupPlayerWrapper();
|
|
39409
39554
|
if (this.settings.player.playerMode !== PlayerMode.Disabled) {
|
|
39410
39555
|
this.setupOrDestroyPlayer();
|
|
@@ -39479,7 +39624,7 @@ class AlphaTabApiBase {
|
|
|
39479
39624
|
this._isDestroyed = true;
|
|
39480
39625
|
this._player.destroy();
|
|
39481
39626
|
this.uiFacade.destroy();
|
|
39482
|
-
this.
|
|
39627
|
+
this._renderer.destroy();
|
|
39483
39628
|
}
|
|
39484
39629
|
/**
|
|
39485
39630
|
* Applies any changes that were done to the settings object.
|
|
@@ -39524,12 +39669,30 @@ class AlphaTabApiBase {
|
|
|
39524
39669
|
if (score) {
|
|
39525
39670
|
ModelUtils.applyPitchOffsets(this.settings, score);
|
|
39526
39671
|
}
|
|
39527
|
-
this.
|
|
39528
|
-
|
|
39529
|
-
|
|
39530
|
-
}
|
|
39672
|
+
this.updateRenderer();
|
|
39673
|
+
this._renderer.updateSettings(this.settings);
|
|
39674
|
+
this.setupOrDestroyPlayer();
|
|
39531
39675
|
this.onSettingsUpdated();
|
|
39532
39676
|
}
|
|
39677
|
+
updateRenderer() {
|
|
39678
|
+
const renderer = this._renderer;
|
|
39679
|
+
if (this.settings.core.useWorkers &&
|
|
39680
|
+
this.uiFacade.areWorkersSupported &&
|
|
39681
|
+
Environment.getRenderEngineFactory(this.settings.core.engine).supportsWorkers) {
|
|
39682
|
+
// switch from non-worker to worker renderer
|
|
39683
|
+
if (renderer.instance instanceof ScoreRenderer) {
|
|
39684
|
+
renderer.destroy();
|
|
39685
|
+
renderer.instance = this.uiFacade.createWorkerRenderer();
|
|
39686
|
+
}
|
|
39687
|
+
}
|
|
39688
|
+
else {
|
|
39689
|
+
// switch from worker to non-worker renderer
|
|
39690
|
+
if (!(renderer.instance instanceof ScoreRenderer)) {
|
|
39691
|
+
renderer.destroy();
|
|
39692
|
+
renderer.instance = new ScoreRenderer(this.settings);
|
|
39693
|
+
}
|
|
39694
|
+
}
|
|
39695
|
+
}
|
|
39533
39696
|
/**
|
|
39534
39697
|
* Initiates a load of the score using the given data.
|
|
39535
39698
|
* @returns true if the data object is supported and a load was initiated, otherwise false
|
|
@@ -39724,30 +39887,33 @@ class AlphaTabApiBase {
|
|
|
39724
39887
|
}
|
|
39725
39888
|
else {
|
|
39726
39889
|
const resizeEventInfo = new ResizeEventArgs();
|
|
39727
|
-
resizeEventInfo.oldWidth = this.
|
|
39890
|
+
resizeEventInfo.oldWidth = this._renderer.width;
|
|
39728
39891
|
resizeEventInfo.newWidth = this.container.width;
|
|
39729
39892
|
resizeEventInfo.settings = this.settings;
|
|
39730
39893
|
this.onResize(resizeEventInfo);
|
|
39731
|
-
this.
|
|
39732
|
-
this.
|
|
39733
|
-
this.
|
|
39894
|
+
this._renderer.updateSettings(this.settings);
|
|
39895
|
+
this._renderer.width = this.container.width;
|
|
39896
|
+
this._renderer.resizeRender();
|
|
39734
39897
|
}
|
|
39735
39898
|
}
|
|
39736
|
-
appendRenderResult(result) {
|
|
39737
|
-
|
|
39899
|
+
appendRenderResult(result, isLast) {
|
|
39900
|
+
// resizing the canvas and wrapper elements at the end is enough
|
|
39901
|
+
// it avoids flickering on resizes and re-renders.
|
|
39902
|
+
// the individual partials are anyhow sized correctly
|
|
39903
|
+
if (isLast) {
|
|
39738
39904
|
this.canvasElement.width = result.totalWidth;
|
|
39739
39905
|
this.canvasElement.height = result.totalHeight;
|
|
39740
39906
|
if (this._cursorWrapper) {
|
|
39741
39907
|
this._cursorWrapper.width = result.totalWidth;
|
|
39742
39908
|
this._cursorWrapper.height = result.totalHeight;
|
|
39743
39909
|
}
|
|
39744
|
-
if (result.width > 0 || result.height > 0) {
|
|
39745
|
-
this.uiFacade.beginAppendRenderResults(result);
|
|
39746
|
-
}
|
|
39747
39910
|
}
|
|
39748
|
-
|
|
39911
|
+
if (result.width > 0 || result.height > 0) {
|
|
39749
39912
|
this.uiFacade.beginAppendRenderResults(result);
|
|
39750
39913
|
}
|
|
39914
|
+
if (isLast) {
|
|
39915
|
+
this.uiFacade.beginAppendRenderResults(null);
|
|
39916
|
+
}
|
|
39751
39917
|
}
|
|
39752
39918
|
updateRenderResult(result) {
|
|
39753
39919
|
if (result && result.renderResult) {
|
|
@@ -39909,13 +40075,10 @@ class AlphaTabApiBase {
|
|
|
39909
40075
|
* ```
|
|
39910
40076
|
*/
|
|
39911
40077
|
render() {
|
|
39912
|
-
if (!this.renderer) {
|
|
39913
|
-
return;
|
|
39914
|
-
}
|
|
39915
40078
|
if (this.uiFacade.canRender) {
|
|
39916
40079
|
// when font is finally loaded, start rendering
|
|
39917
|
-
this.
|
|
39918
|
-
this.
|
|
40080
|
+
this._renderer.width = this.container.width;
|
|
40081
|
+
this._renderer.renderScore(this.score, this._trackIndexes);
|
|
39919
40082
|
}
|
|
39920
40083
|
else {
|
|
39921
40084
|
this.uiFacade.canRenderChanged.on(() => this.render());
|
|
@@ -39990,7 +40153,7 @@ class AlphaTabApiBase {
|
|
|
39990
40153
|
* @since 1.5.0
|
|
39991
40154
|
*/
|
|
39992
40155
|
get boundsLookup() {
|
|
39993
|
-
return this.
|
|
40156
|
+
return this._renderer.boundsLookup;
|
|
39994
40157
|
}
|
|
39995
40158
|
/**
|
|
39996
40159
|
* The alphaSynth player used for playback.
|
|
@@ -40422,6 +40585,10 @@ class AlphaTabApiBase {
|
|
|
40422
40585
|
this._previousTick = 0;
|
|
40423
40586
|
this.destroyCursors();
|
|
40424
40587
|
}
|
|
40588
|
+
/**
|
|
40589
|
+
*
|
|
40590
|
+
* @returns true if a new player was created, false if no player was created (includes destroy & reuse of the current one)
|
|
40591
|
+
*/
|
|
40425
40592
|
setupOrDestroyPlayer() {
|
|
40426
40593
|
let mode = this.settings.player.playerMode;
|
|
40427
40594
|
if (mode === PlayerMode.EnabledAutomatic) {
|
|
@@ -40439,6 +40606,7 @@ class AlphaTabApiBase {
|
|
|
40439
40606
|
let newPlayer = null;
|
|
40440
40607
|
if (mode !== this._actualPlayerMode) {
|
|
40441
40608
|
this.destroyPlayer();
|
|
40609
|
+
this.updateCursors();
|
|
40442
40610
|
switch (mode) {
|
|
40443
40611
|
case PlayerMode.Disabled:
|
|
40444
40612
|
newPlayer = null;
|
|
@@ -40456,9 +40624,9 @@ class AlphaTabApiBase {
|
|
|
40456
40624
|
}
|
|
40457
40625
|
else {
|
|
40458
40626
|
// no change in player mode, just update song info if needed
|
|
40459
|
-
|
|
40627
|
+
this.updateCursors();
|
|
40628
|
+
return false;
|
|
40460
40629
|
}
|
|
40461
|
-
this.updateCursors();
|
|
40462
40630
|
this._actualPlayerMode = mode;
|
|
40463
40631
|
if (!newPlayer) {
|
|
40464
40632
|
return false;
|
|
@@ -40466,6 +40634,13 @@ class AlphaTabApiBase {
|
|
|
40466
40634
|
this._player.instance = newPlayer;
|
|
40467
40635
|
return false;
|
|
40468
40636
|
}
|
|
40637
|
+
/**
|
|
40638
|
+
* Re-creates the midi for the current score and loads it.
|
|
40639
|
+
* @remarks
|
|
40640
|
+
* This will result in the player to stop playback. Some setting changes require re-genration of the midi song.
|
|
40641
|
+
* @category Methods - Player
|
|
40642
|
+
* @since 1.6.0
|
|
40643
|
+
*/
|
|
40469
40644
|
loadMidiForScore() {
|
|
40470
40645
|
if (!this.score) {
|
|
40471
40646
|
return;
|
|
@@ -40869,6 +41044,7 @@ class AlphaTabApiBase {
|
|
|
40869
41044
|
this._barCursor = cursors.barCursor;
|
|
40870
41045
|
this._beatCursor = cursors.beatCursor;
|
|
40871
41046
|
this._selectionWrapper = cursors.selectionWrapper;
|
|
41047
|
+
this._isInitialBeatCursorUpdate = true;
|
|
40872
41048
|
}
|
|
40873
41049
|
if (this._currentBeat !== null) {
|
|
40874
41050
|
this.cursorUpdateBeat(this._currentBeat, false, this._previousTick > 10, 1, true);
|
|
@@ -40908,7 +41084,7 @@ class AlphaTabApiBase {
|
|
|
40908
41084
|
if (!beat) {
|
|
40909
41085
|
return;
|
|
40910
41086
|
}
|
|
40911
|
-
const cache = this.
|
|
41087
|
+
const cache = this._renderer.boundsLookup;
|
|
40912
41088
|
if (!cache) {
|
|
40913
41089
|
return;
|
|
40914
41090
|
}
|
|
@@ -41031,6 +41207,7 @@ class AlphaTabApiBase {
|
|
|
41031
41207
|
if (isPlayingUpdate) {
|
|
41032
41208
|
// we do not "reset" the cursor if we are smoothly moving from left to right.
|
|
41033
41209
|
const jumpCursor = !previousBeatBounds ||
|
|
41210
|
+
this._isInitialBeatCursorUpdate ||
|
|
41034
41211
|
barBounds.y !== previousBeatBounds.barBounds.masterBarBounds.visualBounds.y ||
|
|
41035
41212
|
startBeatX < previousBeatBounds.onNotesX ||
|
|
41036
41213
|
barBoundings.index > previousBeatBounds.barBounds.masterBarBounds.index + 1;
|
|
@@ -41055,13 +41232,16 @@ class AlphaTabApiBase {
|
|
|
41055
41232
|
}
|
|
41056
41233
|
else {
|
|
41057
41234
|
// ticking cursor
|
|
41235
|
+
beatCursor.transitionToX(0, startBeatX);
|
|
41058
41236
|
beatCursor.setBounds(startBeatX, barBounds.y, 1, barBounds.h);
|
|
41059
41237
|
}
|
|
41238
|
+
this._isInitialBeatCursorUpdate = false;
|
|
41060
41239
|
}
|
|
41061
|
-
|
|
41062
|
-
|
|
41063
|
-
this.uiFacade.removeHighlights();
|
|
41240
|
+
else {
|
|
41241
|
+
this._isInitialBeatCursorUpdate = true;
|
|
41064
41242
|
}
|
|
41243
|
+
// if playing, animate the cursor to the next beat
|
|
41244
|
+
this.uiFacade.removeHighlights();
|
|
41065
41245
|
// actively playing? -> animate cursor and highlight items
|
|
41066
41246
|
let shouldNotifyBeatChange = false;
|
|
41067
41247
|
if (isPlayingUpdate) {
|
|
@@ -41225,11 +41405,11 @@ class AlphaTabApiBase {
|
|
|
41225
41405
|
}
|
|
41226
41406
|
const relX = e.getX(this.canvasElement);
|
|
41227
41407
|
const relY = e.getY(this.canvasElement);
|
|
41228
|
-
const beat = this.
|
|
41408
|
+
const beat = this._renderer.boundsLookup?.getBeatAtPos(relX, relY) ?? null;
|
|
41229
41409
|
if (beat) {
|
|
41230
41410
|
this.onBeatMouseDown(e, beat);
|
|
41231
41411
|
if (this.settings.core.includeNoteBounds) {
|
|
41232
|
-
const note = this.
|
|
41412
|
+
const note = this._renderer.boundsLookup?.getNoteAtPos(beat, relX, relY);
|
|
41233
41413
|
if (note) {
|
|
41234
41414
|
this.onNoteMouseDown(e, note);
|
|
41235
41415
|
}
|
|
@@ -41242,11 +41422,11 @@ class AlphaTabApiBase {
|
|
|
41242
41422
|
}
|
|
41243
41423
|
const relX = e.getX(this.canvasElement);
|
|
41244
41424
|
const relY = e.getY(this.canvasElement);
|
|
41245
|
-
const beat = this.
|
|
41425
|
+
const beat = this._renderer.boundsLookup?.getBeatAtPos(relX, relY) ?? null;
|
|
41246
41426
|
if (beat) {
|
|
41247
41427
|
this.onBeatMouseMove(e, beat);
|
|
41248
41428
|
if (this._noteMouseDown) {
|
|
41249
|
-
const note = this.
|
|
41429
|
+
const note = this._renderer.boundsLookup?.getNoteAtPos(beat, relX, relY);
|
|
41250
41430
|
if (note) {
|
|
41251
41431
|
this.onNoteMouseMove(e, note);
|
|
41252
41432
|
}
|
|
@@ -41262,11 +41442,11 @@ class AlphaTabApiBase {
|
|
|
41262
41442
|
}
|
|
41263
41443
|
const relX = e.getX(this.canvasElement);
|
|
41264
41444
|
const relY = e.getY(this.canvasElement);
|
|
41265
|
-
const beat = this.
|
|
41445
|
+
const beat = this._renderer.boundsLookup?.getBeatAtPos(relX, relY) ?? null;
|
|
41266
41446
|
this.onBeatMouseUp(e, beat);
|
|
41267
41447
|
if (this._noteMouseDown) {
|
|
41268
41448
|
if (beat) {
|
|
41269
|
-
const note = this.
|
|
41449
|
+
const note = this._renderer.boundsLookup?.getNoteAtPos(beat, relX, relY) ?? null;
|
|
41270
41450
|
this.onNoteMouseUp(e, note);
|
|
41271
41451
|
}
|
|
41272
41452
|
else {
|
|
@@ -41274,7 +41454,7 @@ class AlphaTabApiBase {
|
|
|
41274
41454
|
}
|
|
41275
41455
|
}
|
|
41276
41456
|
});
|
|
41277
|
-
this.
|
|
41457
|
+
this._renderer.postRenderFinished.on(() => {
|
|
41278
41458
|
if (!this._selectionStart ||
|
|
41279
41459
|
this.settings.player.playerMode === PlayerMode.Disabled ||
|
|
41280
41460
|
!this.settings.player.enableCursor ||
|
|
@@ -41285,7 +41465,7 @@ class AlphaTabApiBase {
|
|
|
41285
41465
|
});
|
|
41286
41466
|
}
|
|
41287
41467
|
cursorSelectRange(startBeat, endBeat) {
|
|
41288
|
-
const cache = this.
|
|
41468
|
+
const cache = this._renderer.boundsLookup;
|
|
41289
41469
|
if (!cache) {
|
|
41290
41470
|
return;
|
|
41291
41471
|
}
|
|
@@ -41354,7 +41534,8 @@ class AlphaTabApiBase {
|
|
|
41354
41534
|
}
|
|
41355
41535
|
this.scoreLoaded.trigger(score);
|
|
41356
41536
|
this.uiFacade.triggerEvent(this.container, 'scoreLoaded', score);
|
|
41357
|
-
if (this.setupOrDestroyPlayer()) {
|
|
41537
|
+
if (!this.setupOrDestroyPlayer()) {
|
|
41538
|
+
// feed midi into current player (a new player will trigger a midi generation once the player is ready)
|
|
41358
41539
|
this.loadMidiForScore();
|
|
41359
41540
|
}
|
|
41360
41541
|
}
|
|
@@ -41384,7 +41565,7 @@ class AlphaTabApiBase {
|
|
|
41384
41565
|
return;
|
|
41385
41566
|
}
|
|
41386
41567
|
this._currentBeat = null;
|
|
41387
|
-
this.cursorUpdateTick(this._previousTick, false, 1,
|
|
41568
|
+
this.cursorUpdateTick(this._previousTick, false, 1, true, true);
|
|
41388
41569
|
this.postRenderFinished.trigger();
|
|
41389
41570
|
this.uiFacade.triggerEvent(this.container, 'postRenderFinished', null);
|
|
41390
41571
|
}
|
|
@@ -46940,7 +47121,7 @@ class StaffSystem {
|
|
|
46940
47121
|
return this.masterBarsRenderers[0].masterBar.index;
|
|
46941
47122
|
}
|
|
46942
47123
|
get lastBarIndex() {
|
|
46943
|
-
return this.masterBarsRenderers[this.masterBarsRenderers.length - 1].
|
|
47124
|
+
return this.masterBarsRenderers[this.masterBarsRenderers.length - 1].lastMasterBarIndex;
|
|
46944
47125
|
}
|
|
46945
47126
|
addMasterBarRenderers(tracks, renderers) {
|
|
46946
47127
|
if (tracks.length === 0) {
|
|
@@ -47754,6 +47935,9 @@ class ScoreLayout {
|
|
|
47754
47935
|
}
|
|
47755
47936
|
}
|
|
47756
47937
|
}
|
|
47938
|
+
else {
|
|
47939
|
+
this.tuningGlyph = null;
|
|
47940
|
+
}
|
|
47757
47941
|
}
|
|
47758
47942
|
// chord diagram glyphs
|
|
47759
47943
|
if (notation.isNotationElementVisible(NotationElement.ChordDiagrams)) {
|
|
@@ -47782,6 +47966,12 @@ class ScoreLayout {
|
|
|
47782
47966
|
}
|
|
47783
47967
|
}
|
|
47784
47968
|
}
|
|
47969
|
+
if (this.chordDiagrams.isEmpty) {
|
|
47970
|
+
this.chordDiagrams = null;
|
|
47971
|
+
}
|
|
47972
|
+
}
|
|
47973
|
+
else {
|
|
47974
|
+
this.chordDiagrams = null;
|
|
47785
47975
|
}
|
|
47786
47976
|
}
|
|
47787
47977
|
createEmptyStaffSystem() {
|
|
@@ -60525,9 +60715,9 @@ class VersionInfo {
|
|
|
60525
60715
|
print(`build date: ${VersionInfo.date}`);
|
|
60526
60716
|
}
|
|
60527
60717
|
}
|
|
60528
|
-
VersionInfo.version = '1.6.0-alpha.
|
|
60529
|
-
VersionInfo.date = '2025-05-
|
|
60530
|
-
VersionInfo.commit = '
|
|
60718
|
+
VersionInfo.version = '1.6.0-alpha.1415';
|
|
60719
|
+
VersionInfo.date = '2025-05-19T16:08:22.342Z';
|
|
60720
|
+
VersionInfo.commit = '459db69f8896a2ea8822ce5d49dcc824edd36521';
|
|
60531
60721
|
|
|
60532
60722
|
/**
|
|
60533
60723
|
* A factory for custom layout engines.
|
package/dist/alphaTab.d.ts
CHANGED
|
@@ -471,6 +471,7 @@ export declare class AlphaTabApiBase<TSettings> {
|
|
|
471
471
|
private _tracks;
|
|
472
472
|
private _actualPlayerMode;
|
|
473
473
|
private _player;
|
|
474
|
+
private _renderer;
|
|
474
475
|
/**
|
|
475
476
|
* The actual player mode which is currently active (e.g. allows determining whether a backing track or the synthesizer is active).
|
|
476
477
|
*/
|
|
@@ -516,7 +517,7 @@ export declare class AlphaTabApiBase<TSettings> {
|
|
|
516
517
|
* @category Properties - Core
|
|
517
518
|
* @since 0.9.4
|
|
518
519
|
*/
|
|
519
|
-
|
|
520
|
+
get renderer(): IScoreRenderer;
|
|
520
521
|
/**
|
|
521
522
|
* The score holding all information about the song being rendered
|
|
522
523
|
* @category Properties - Core
|
|
@@ -682,6 +683,7 @@ export declare class AlphaTabApiBase<TSettings> {
|
|
|
682
683
|
* ```
|
|
683
684
|
*/
|
|
684
685
|
updateSettings(): void;
|
|
686
|
+
private updateRenderer;
|
|
685
687
|
/**
|
|
686
688
|
* Initiates a load of the score using the given data.
|
|
687
689
|
* @returns true if the data object is supported and a load was initiated, otherwise false
|
|
@@ -1376,8 +1378,19 @@ export declare class AlphaTabApiBase<TSettings> {
|
|
|
1376
1378
|
get isLooping(): boolean;
|
|
1377
1379
|
set isLooping(value: boolean);
|
|
1378
1380
|
private destroyPlayer;
|
|
1381
|
+
/**
|
|
1382
|
+
*
|
|
1383
|
+
* @returns true if a new player was created, false if no player was created (includes destroy & reuse of the current one)
|
|
1384
|
+
*/
|
|
1379
1385
|
private setupOrDestroyPlayer;
|
|
1380
|
-
|
|
1386
|
+
/**
|
|
1387
|
+
* Re-creates the midi for the current score and loads it.
|
|
1388
|
+
* @remarks
|
|
1389
|
+
* This will result in the player to stop playback. Some setting changes require re-genration of the midi song.
|
|
1390
|
+
* @category Methods - Player
|
|
1391
|
+
* @since 1.6.0
|
|
1392
|
+
*/
|
|
1393
|
+
loadMidiForScore(): void;
|
|
1381
1394
|
/**
|
|
1382
1395
|
* Changes the volume of the given tracks.
|
|
1383
1396
|
* @param tracks The tracks for which the volume should be changed.
|
|
@@ -1703,6 +1716,7 @@ export declare class AlphaTabApiBase<TSettings> {
|
|
|
1703
1716
|
private _previousTick;
|
|
1704
1717
|
private _currentBeat;
|
|
1705
1718
|
private _currentBeatBounds;
|
|
1719
|
+
private _isInitialBeatCursorUpdate;
|
|
1706
1720
|
private _previousStateForCursor;
|
|
1707
1721
|
private _previousCursorCache;
|
|
1708
1722
|
private _lastScroll;
|
|
@@ -2741,7 +2755,43 @@ export declare class AlphaTabApiBase<TSettings> {
|
|
|
2741
2755
|
*/
|
|
2742
2756
|
get playbackRangeChanged(): IEventEmitterOfT<PlaybackRangeChangedEventArgs>;
|
|
2743
2757
|
private onPlaybackRangeChanged;
|
|
2744
|
-
|
|
2758
|
+
/**
|
|
2759
|
+
* This event is fired when a settings update was requested.
|
|
2760
|
+
*
|
|
2761
|
+
* @eventProperty
|
|
2762
|
+
* @category Events - Core
|
|
2763
|
+
* @since 1.6.0
|
|
2764
|
+
*
|
|
2765
|
+
* @example
|
|
2766
|
+
* JavaScript
|
|
2767
|
+
* ```js
|
|
2768
|
+
* const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab'));
|
|
2769
|
+
* api.settingsUpdated.on(() => {
|
|
2770
|
+
* updateSettingsUI(api.settings);
|
|
2771
|
+
* });
|
|
2772
|
+
* ```
|
|
2773
|
+
*
|
|
2774
|
+
* @example
|
|
2775
|
+
* C#
|
|
2776
|
+
* ```cs
|
|
2777
|
+
* var api = new AlphaTabApi<MyControl>(...);
|
|
2778
|
+
* api.SettingsUpdated.On(() =>
|
|
2779
|
+
* {
|
|
2780
|
+
* UpdateSettingsUI(api.settings);
|
|
2781
|
+
* });
|
|
2782
|
+
* ```
|
|
2783
|
+
*
|
|
2784
|
+
* @example
|
|
2785
|
+
* Android
|
|
2786
|
+
* ```kotlin
|
|
2787
|
+
* val api = AlphaTabApi<MyControl>(...)
|
|
2788
|
+
* api.SettingsUpdated.on {
|
|
2789
|
+
* updateSettingsUI(api.settings)
|
|
2790
|
+
* }
|
|
2791
|
+
* ```
|
|
2792
|
+
*
|
|
2793
|
+
*/
|
|
2794
|
+
settingsUpdated: IEventEmitter;
|
|
2745
2795
|
private onSettingsUpdated;
|
|
2746
2796
|
/**
|
|
2747
2797
|
* Loads and lists the available output devices which can be used by the player.
|