Selection change events
Sync a right-side properties inspector to the selected range. Move drag handles that ride the edges of the highlight. Show a "5 bars selected" pill above the range while the user drags. Every time the highlight overlay changes โ from a user drag, from a programmatic highlightPlaybackRange call, from a clear โ alphaTab fires playbackRangeHighlightChanged with the current start and end beats plus the pixel rectangles being painted. The demo below wires drag handles to this event; the event log on the side shows the payload each fire delivers.
startBeat: โ endBeat: โ highlightBlocks: 0
The event payloadโ
The handler receives a PlaybackHighlightChangeEventArgs object. Every field is optional โ an empty object arrives when the selection was cleared or the render has not settled yet.
startBeatโ theBeatwhere the selection starts.undefinedwhen there is no selection.startBeatBoundsโ theBeatBoundsfor that beat, ready to position a marker.endBeatโ theBeatwhere the selection ends.endBeatBoundsโ theBeatBoundsfor the end beat.highlightBlocksโ the array ofBoundsrectangles that make up the overlay. A single-line selection has one entry; a selection spanning three staff systems has three. Each rectangle hasx,y,w,hin render coordinates.
The event fires during the drag, not only on release. Use it to keep drag handles pinned to the current edges without polling.
Show it in codeโ
import * as alphaTab from '@coderline/alphatab';
const container = getAlphaTabContainer();
const startHandle = document.getElementById('selection-start-handle');
const endHandle = document.getElementById('selection-end-handle');
const api = new alphaTab.AlphaTabApi(container, {
core: { file: '/scores/song.gp' },
player: { playerMode: alphaTab.PlayerMode.EnabledAutomatic },
});
api.playbackRangeHighlightChanged.on((e) => {
if (!e.highlightBlocks || e.highlightBlocks.length === 0) {
startHandle.hidden = true;
endHandle.hidden = true;
return;
}
const first = e.highlightBlocks[0];
startHandle.hidden = false;
startHandle.style.left = `${first.x}px`;
startHandle.style.top = `${first.y}px`;
startHandle.style.height = `${first.h}px`;
const last = e.highlightBlocks[e.highlightBlocks.length - 1];
endHandle.hidden = false;
endHandle.style.left = `${last.x + last.w}px`;
endHandle.style.top = `${last.y}px`;
endHandle.style.height = `${last.h}px`;
});
getAlphaTabContainer() is a placeholder for the platform-specific step of obtaining the render target. Every other line runs unchanged on all three runtimes.
Where to look nextโ
- Range selection โ the three methods that drive the highlight the event reports on.
- Bounds lookup โ the geometry system that produces the
highlightBlocksrectangles. playbackRangeHighlightChangedin the API reference.PlaybackHighlightChangeEventArgsin the types reference.