mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Merge 54d77f76f8 into a35c8a97d2
This commit is contained in:
commit
2fcf82be97
1 changed files with 61 additions and 21 deletions
|
|
@ -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;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue