1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00
This commit is contained in:
mimoz 2025-12-31 11:12:52 -08:00 committed by GitHub
commit 2fcf82be97
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -36,7 +36,9 @@ import "./check_native_interop.js";
class PromiseHandler { class PromiseHandler {
constructor() { constructor() {
/** @type {number} */
this.lastPromiseId = 0; this.lastPromiseId = 0;
/** @type {Map<number, any>} */
this.promises = new Map(); this.promises = new Map();
window.__JUCE__.backend.addEventListener( window.__JUCE__.backend.addEventListener(
@ -50,6 +52,9 @@ class PromiseHandler {
); );
} }
/**
* @returns {[number, Promise<any>]}
*/
createPromise() { createPromise() {
const promiseId = this.lastPromiseId++; const promiseId = this.lastPromiseId++;
const result = new Promise((resolve, reject) => { const result = new Promise((resolve, reject) => {
@ -68,7 +73,7 @@ const promiseHandler = new PromiseHandler();
* The provided name should be the same as the name argument passed to * The provided name should be the same as the name argument passed to
* WebBrowserComponent::Options.withNativeFunction() on the backend. * WebBrowserComponent::Options.withNativeFunction() on the backend.
* *
* @param {String} name * @param {string} name
*/ */
function getNativeFunction(name) { function getNativeFunction(name) {
if (!window.__JUCE__.initialisationData.__juce__functions.includes(name)) if (!window.__JUCE__.initialisationData.__juce__functions.includes(name))
@ -95,16 +100,23 @@ function getNativeFunction(name) {
class ListenerList { class ListenerList {
constructor() { constructor() {
/** @type {Map<number, (args: any) => any>} */
this.listeners = new Map(); this.listeners = new Map();
this.listenerId = 0; this.listenerId = 0;
} }
/**
* @param {(args: any) => any} fn
*/
addListener(fn) { addListener(fn) {
const newListenerId = this.listenerId++; const newListenerId = this.listenerId++;
this.listeners.set(newListenerId, fn); this.listeners.set(newListenerId, fn);
return newListenerId; return newListenerId;
} }
/**
* @param {number} id
*/
removeListener(id) { removeListener(id) {
if (this.listeners.has(id)) { if (this.listeners.has(id)) {
this.listeners.delete(id); this.listeners.delete(id);
@ -129,10 +141,11 @@ const SliderControl_sliderDragEndedEventId = "sliderDragEnded";
* *
* Use getSliderState() to create a SliderState object. This object will be synchronised with the * Use getSliderState() to create a SliderState object. This object will be synchronised with the
* WebSliderRelay backend object that was created using the same unique name. * WebSliderRelay backend object that was created using the same unique name.
*
* @param {String} name
*/ */
class SliderState { class SliderState {
/**
* @param {string} name
*/
constructor(name) { constructor(name) {
if (!window.__JUCE__.initialisationData.__juce__sliders.includes(name)) if (!window.__JUCE__.initialisationData.__juce__sliders.includes(name))
console.warn( console.warn(
@ -173,7 +186,7 @@ class SliderState {
* The meaning of this range is the same as in the case of * The meaning of this range is the same as in the case of
* AudioProcessorParameter::getValue() (C++). * AudioProcessorParameter::getValue() (C++).
* *
* @param {String} name * @param {number} newValue
*/ */
setNormalisedValue(newValue) { setNormalisedValue(newValue) {
this.scaledValue = this.snapToLegalValue( this.scaledValue = this.snapToLegalValue(
@ -233,8 +246,6 @@ class SliderState {
* *
* The meaning of this range is the same as in the case of * The meaning of this range is the same as in the case of
* AudioProcessorParameter::getValue() (C++). * AudioProcessorParameter::getValue() (C++).
*
* @param {String} name
*/ */
getNormalisedValue() { getNormalisedValue() {
return Math.pow( return Math.pow(
@ -244,7 +255,11 @@ class SliderState {
); );
} }
/** Internal. */ /**
* @param {number} normalisedValue
* @returns {number}
* @internal
*/
normalisedToScaledValue(normalisedValue) { normalisedToScaledValue(normalisedValue) {
return ( return (
Math.pow(normalisedValue, 1 / this.properties.skew) * Math.pow(normalisedValue, 1 / this.properties.skew) *
@ -253,7 +268,11 @@ class SliderState {
); );
} }
/** Internal. */ /**
* @param {number} value
* @returns {number}
* @internal
*/
snapToLegalValue(value) { snapToLegalValue(value) {
const interval = this.properties.interval; const interval = this.properties.interval;
@ -270,6 +289,7 @@ class SliderState {
} }
} }
/** @type {Map<string, SliderState>} */
const sliderStates = new Map(); const sliderStates = new Map();
for (const sliderName of window.__JUCE__.initialisationData.__juce__sliders) for (const sliderName of window.__JUCE__.initialisationData.__juce__sliders)
@ -282,7 +302,7 @@ for (const sliderName of window.__JUCE__.initialisationData.__juce__sliders)
* To register a WebSliderRelay object create one with the right name and add it to the * To register a WebSliderRelay object create one with the right name and add it to the
* WebBrowserComponent::Options struct using withOptionsFrom. * WebBrowserComponent::Options struct using withOptionsFrom.
* *
* @param {String} name * @param {string} name
*/ */
function getSliderState(name) { function getSliderState(name) {
if (!sliderStates.has(name)) sliderStates.set(name, new SliderState(name)); if (!sliderStates.has(name)) sliderStates.set(name, new SliderState(name));
@ -296,10 +316,11 @@ function getSliderState(name) {
* *
* Use getToggleState() to create a ToggleState object. This object will be synchronised with the * Use getToggleState() to create a ToggleState object. This object will be synchronised with the
* WebToggleRelay backend object that was created using the same unique name. * WebToggleRelay backend object that was created using the same unique name.
*
* @param {String} name
*/ */
class ToggleState { class ToggleState {
/**
* @param {string} name
*/
constructor(name) { constructor(name) {
if (!window.__JUCE__.initialisationData.__juce__toggles.includes(name)) if (!window.__JUCE__.initialisationData.__juce__toggles.includes(name))
console.warn( console.warn(
@ -332,7 +353,10 @@ class ToggleState {
return this.value; return this.value;
} }
/** Informs the backend to change the associated WebToggleRelay's (C++) state. */ /**
* Informs the backend to change the associated WebToggleRelay's (C++) state.
* @param {boolean} newValue
*/
setValue(newValue) { setValue(newValue) {
this.value = newValue; this.value = newValue;
@ -357,6 +381,7 @@ class ToggleState {
} }
} }
/** @type {Map<string, ToggleState>} */
const toggleStates = new Map(); const toggleStates = new Map();
for (const name of window.__JUCE__.initialisationData.__juce__toggles) for (const name of window.__JUCE__.initialisationData.__juce__toggles)
@ -369,7 +394,7 @@ for (const name of window.__JUCE__.initialisationData.__juce__toggles)
* To register a WebToggleButtonRelay object create one with the right name and add it to the * To register a WebToggleButtonRelay object create one with the right name and add it to the
* WebBrowserComponent::Options struct using withOptionsFrom. * WebBrowserComponent::Options struct using withOptionsFrom.
* *
* @param {String} name * @param {string} name
*/ */
function getToggleState(name) { function getToggleState(name) {
if (!toggleStates.has(name)) toggleStates.set(name, new ToggleState(name)); if (!toggleStates.has(name)) toggleStates.set(name, new ToggleState(name));
@ -383,10 +408,11 @@ function getToggleState(name) {
* *
* Use getComboBoxState() to create a ComboBoxState object. This object will be synchronised with the * Use getComboBoxState() to create a ComboBoxState object. This object will be synchronised with the
* WebComboBoxRelay backend object that was created using the same unique name. * WebComboBoxRelay backend object that was created using the same unique name.
*
* @param {String} name
*/ */
class ComboBoxState { class ComboBoxState {
/**
* @param {string} name
*/
constructor(name) { constructor(name) {
if (!window.__JUCE__.initialisationData.__juce__comboBoxes.includes(name)) if (!window.__JUCE__.initialisationData.__juce__comboBoxes.includes(name))
console.warn( console.warn(
@ -401,6 +427,7 @@ class ComboBoxState {
this.properties = { this.properties = {
name: "", name: "",
parameterIndex: -1, parameterIndex: -1,
/** @type {string[]} */
choices: [], choices: [],
}; };
this.valueChangedEvent = new ListenerList(); this.valueChangedEvent = new ListenerList();
@ -430,6 +457,8 @@ class ComboBoxState {
* *
* This should be called with the index identifying the selected element from the * This should be called with the index identifying the selected element from the
* properties.choices array. * properties.choices array.
*
* @param {number} index
*/ */
setChoiceIndex(index) { setChoiceIndex(index) {
const numItems = this.properties.choices.length; const numItems = this.properties.choices.length;
@ -456,6 +485,7 @@ class ComboBoxState {
} }
} }
/** @type {Map<string, ComboBoxState>} */
const comboBoxStates = new Map(); const comboBoxStates = new Map();
for (const name of window.__JUCE__.initialisationData.__juce__comboBoxes) for (const name of window.__JUCE__.initialisationData.__juce__comboBoxes)
@ -468,7 +498,7 @@ for (const name of window.__JUCE__.initialisationData.__juce__comboBoxes)
* To register a WebComboBoxRelay object create one with the right name and add it to the * To register a WebComboBoxRelay object create one with the right name and add it to the
* WebBrowserComponent::Options struct using withOptionsFrom. * WebBrowserComponent::Options struct using withOptionsFrom.
* *
* @param {String} name * @param {string} name
*/ */
function getComboBoxState(name) { function getComboBoxState(name) {
if (!comboBoxStates.has(name)) if (!comboBoxStates.has(name))
@ -480,7 +510,7 @@ function getComboBoxState(name) {
/** /**
* Appends a platform-specific prefix to the path to ensure that a request sent to this address will * Appends a platform-specific prefix to the path to ensure that a request sent to this address will
* be received by the backend's ResourceProvider. * be received by the backend's ResourceProvider.
* @param {String} path * @param {string} path
*/ */
function getBackendResourceAddress(path) { function getBackendResourceAddress(path) {
const platform = const platform =
@ -516,16 +546,23 @@ function getBackendResourceAddress(path) {
* *
* Whenever there is a change in this value, an event is emitted to the frontend with the new value. * Whenever there is a change in this value, an event is emitted to the frontend with the new value.
* You can use a ControlParameterIndexReceiver object on the backend to listen to these events. * You can use a ControlParameterIndexReceiver object on the backend to listen to these events.
*
* @param {String} controlParameterIndexAnnotation
*/ */
class ControlParameterIndexUpdater { class ControlParameterIndexUpdater {
/**
* @param {string} controlParameterIndexAnnotation
*/
constructor(controlParameterIndexAnnotation) { constructor(controlParameterIndexAnnotation) {
/** @type {string} */
this.controlParameterIndexAnnotation = controlParameterIndexAnnotation; this.controlParameterIndexAnnotation = controlParameterIndexAnnotation;
/** @type {Element | null} */
this.lastElement = null; this.lastElement = null;
this.lastControlParameterIndex = null; /** @type {number} */
this.lastControlParameterIndex = -1;
} }
/**
* @param {MouseEvent} event
*/
handleMouseMove(event) { handleMouseMove(event) {
const currentElement = document.elementFromPoint( const currentElement = document.elementFromPoint(
event.clientX, event.clientX,
@ -550,6 +587,9 @@ class ControlParameterIndexUpdater {
} }
//============================================================================== //==============================================================================
/**
* @param {Element} element
*/
#getControlParameterIndex(element) { #getControlParameterIndex(element) {
const isValidNonRootElement = (e) => { const isValidNonRootElement = (e) => {
return e !== null && e !== document.documentElement; return e !== null && e !== document.documentElement;
@ -557,7 +597,7 @@ class ControlParameterIndexUpdater {
while (isValidNonRootElement(element)) { while (isValidNonRootElement(element)) {
if (element.hasAttribute(this.controlParameterIndexAnnotation)) { if (element.hasAttribute(this.controlParameterIndexAnnotation)) {
return element.getAttribute(this.controlParameterIndexAnnotation); return Number(element.getAttribute(this.controlParameterIndexAnnotation));
} }
element = element.parentElement; element = element.parentElement;