Add units to MIDI range control
This time taking into account logarithmic scale. Refactored range conversion functions across the codebase too, as there were similar functions in different files.
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
// Copyright (c) Robin E.R. Davies
|
// Copyright (c) 2022 Robin Davies
|
||||||
|
// Copyright (c) Fulgencio Ruiz Rubio.
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
// this software and associated documentation files (the "Software"), to deal in
|
// this software and associated documentation files (the "Software"), to deal in
|
||||||
@@ -835,15 +836,44 @@ export class UiControl implements Deserializable<UiControl> {
|
|||||||
|
|
||||||
valueToRange(value: number): number {
|
valueToRange(value: number): number {
|
||||||
if (this.toggled_property) return value === 0 ? 0 : 1;
|
if (this.toggled_property) return value === 0 ? 0 : 1;
|
||||||
|
|
||||||
if (this.integer_property || this.enumeration_property) {
|
if (this.integer_property || this.enumeration_property) {
|
||||||
value = Math.round(value);
|
value = Math.round(value);
|
||||||
}
|
}
|
||||||
let range = (value - this.min_value) / (this.max_value - this.min_value);
|
let range: number;
|
||||||
|
if (this.is_logarithmic) {
|
||||||
|
let minValue = this.min_value;
|
||||||
|
if (minValue === 0) // LSP plugins do this.
|
||||||
|
{
|
||||||
|
minValue = 0.0001;
|
||||||
|
}
|
||||||
|
range = Math.log(value / minValue) / Math.log(this.max_value / minValue);
|
||||||
|
if (!isFinite(range)) {
|
||||||
|
if (range < 0) {
|
||||||
|
range = 0;
|
||||||
|
} else {
|
||||||
|
range = 1.0;
|
||||||
|
}
|
||||||
|
} else if (isNaN(range)) {
|
||||||
|
range = 0;
|
||||||
|
}
|
||||||
|
if (this.range_steps > 1) {
|
||||||
|
range = Math.round(range * (this.range_steps - 1)) / (this.range_steps - 1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
range = (value - this.min_value) / (this.max_value - this.min_value);
|
||||||
|
if (!isFinite(range)) {
|
||||||
|
if (range < 0) {
|
||||||
|
range = 0;
|
||||||
|
} else {
|
||||||
|
range = 1.0;
|
||||||
|
}
|
||||||
|
} else if (isNaN(range)) {
|
||||||
|
range = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (range > 1) range = 1;
|
if (range > 1) range = 1;
|
||||||
if (range < 0) range = 0;
|
if (range < 0) range = 0;
|
||||||
|
|
||||||
|
|
||||||
return range;
|
return range;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -852,17 +882,67 @@ export class UiControl implements Deserializable<UiControl> {
|
|||||||
if (range > 1) range = 1;
|
if (range > 1) range = 1;
|
||||||
|
|
||||||
if (this.toggled_property) return range === 0 ? 0 : 1;
|
if (this.toggled_property) return range === 0 ? 0 : 1;
|
||||||
|
if (this.range_steps > 1) {
|
||||||
|
range = Math.round(range * (this.range_steps - 1)) / (this.range_steps - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
let value: number;
|
||||||
|
|
||||||
let value = range * (this.max_value - this.min_value) + this.min_value;
|
if (this.min_value === this.max_value) {
|
||||||
if (this.integer_property || this.enumeration_property) {
|
value = this.min_value;
|
||||||
value = Math.round(value);
|
} else {
|
||||||
|
if (this.is_logarithmic) {
|
||||||
|
let minValue = this.min_value;
|
||||||
|
if (minValue === 0) // LSP controls.
|
||||||
|
{
|
||||||
|
minValue = 0.0001;
|
||||||
|
}
|
||||||
|
value = minValue * Math.pow(this.max_value / minValue, range);
|
||||||
|
if (!isFinite(value)) {
|
||||||
|
value = this.max_value;
|
||||||
|
} else if (isNaN(value)) {
|
||||||
|
value = this.min_value;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
value = range * (this.max_value - this.min_value) + this.min_value;
|
||||||
|
}
|
||||||
|
if (this.integer_property) {
|
||||||
|
value = Math.round(value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
clampValue(value: number): number {
|
clampValue(value: number): number {
|
||||||
return this.rangeToValue(this.valueToRange(value));
|
return this.rangeToValue(this.valueToRange(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getDisplayUnits(): string {
|
||||||
|
if (this.custom_units !== "") {
|
||||||
|
return this.custom_units.replace("%f", "");
|
||||||
|
}
|
||||||
|
switch (this.units) {
|
||||||
|
case Units.bar: return "bar";
|
||||||
|
case Units.beat: return "beats";
|
||||||
|
case Units.bpm: return "bpm";
|
||||||
|
case Units.cent: return "cents";
|
||||||
|
case Units.cm: return "cm";
|
||||||
|
case Units.db: return "dB";
|
||||||
|
case Units.hz: return "Hz";
|
||||||
|
case Units.khz: return "kHz";
|
||||||
|
case Units.km: return "km";
|
||||||
|
case Units.m: return "m";
|
||||||
|
case Units.mhz: return "MHz";
|
||||||
|
case Units.midiNote: return "MIDI note";
|
||||||
|
case Units.min: return "min";
|
||||||
|
case Units.ms: return "ms";
|
||||||
|
case Units.pc: return "%";
|
||||||
|
case Units.s: return "s";
|
||||||
|
case Units.semitone12TET: return "st";
|
||||||
|
default: return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
formatDisplayValue(value: number): string {
|
formatDisplayValue(value: number): string {
|
||||||
if (this.integer_property) {
|
if (this.integer_property) {
|
||||||
value = Math.round(value);
|
value = Math.round(value);
|
||||||
@@ -893,56 +973,9 @@ export class UiControl implements Deserializable<UiControl> {
|
|||||||
return semitone12TETValue(value);
|
return semitone12TETValue(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
let text = this.formatShortValue(value);
|
return this.formatShortValue(value) + this.getDisplayUnits();
|
||||||
|
|
||||||
switch (this.units) {
|
|
||||||
case Units.bpm:
|
|
||||||
text += "bpm";
|
|
||||||
break;
|
|
||||||
case Units.cent:
|
|
||||||
text += "cents";
|
|
||||||
break;
|
|
||||||
case Units.cm:
|
|
||||||
text += "cm";
|
|
||||||
break;
|
|
||||||
case Units.db:
|
|
||||||
text += "dB";
|
|
||||||
break;
|
|
||||||
case Units.hz:
|
|
||||||
text += "Hz";
|
|
||||||
break;
|
|
||||||
case Units.khz:
|
|
||||||
text += "kHz";
|
|
||||||
break;
|
|
||||||
case Units.km:
|
|
||||||
text += "km";
|
|
||||||
break;
|
|
||||||
case Units.m:
|
|
||||||
text += "m";
|
|
||||||
break;
|
|
||||||
case Units.mhz:
|
|
||||||
text += "MHz";
|
|
||||||
break;
|
|
||||||
case Units.min:
|
|
||||||
text += "min";
|
|
||||||
break;
|
|
||||||
case Units.ms:
|
|
||||||
text += "ms";
|
|
||||||
break;
|
|
||||||
case Units.pc:
|
|
||||||
text += "%";
|
|
||||||
break;
|
|
||||||
case Units.unknown:
|
|
||||||
if (this.custom_units !== "") {
|
|
||||||
text = this.custom_units.replace("%f", text);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
return text;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
formatShortValue(value: number): string {
|
formatShortValue(value: number): string {
|
||||||
if (this.enumeration_property) {
|
if (this.enumeration_property) {
|
||||||
for (let i = 0; i < this.scale_points.length; ++i) {
|
for (let i = 0; i < this.scale_points.length; ++i) {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
// Copyright (c) Robin E.R. Davies
|
// Copyright (c) 2022 Robin Davies
|
||||||
|
// Copyright (c) Fulgencio Ruiz Rubio.
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
// this software and associated documentation files (the "Software"), to deal in
|
// this software and associated documentation files (the "Software"), to deal in
|
||||||
@@ -25,7 +26,7 @@ import { withStyles } from "tss-react/mui";
|
|||||||
import { createStyles } from './WithStyles';
|
import { createStyles } from './WithStyles';
|
||||||
import Snackbar from '@mui/material/Snackbar';
|
import Snackbar from '@mui/material/Snackbar';
|
||||||
|
|
||||||
import { UiPlugin } from './Lv2Plugin';
|
import { UiPlugin, UiControl } from './Lv2Plugin';
|
||||||
|
|
||||||
import MenuItem from '@mui/material/MenuItem';
|
import MenuItem from '@mui/material/MenuItem';
|
||||||
import Select from '@mui/material/Select';
|
import Select from '@mui/material/Select';
|
||||||
@@ -96,6 +97,7 @@ interface MidiBindingViewProps extends WithStyles<typeof styles> {
|
|||||||
midiBinding: MidiBinding;
|
midiBinding: MidiBinding;
|
||||||
midiControlType: MidiControlType;
|
midiControlType: MidiControlType;
|
||||||
canDoTapTempo: boolean;
|
canDoTapTempo: boolean;
|
||||||
|
uiControl?: UiControl;
|
||||||
onChange: (instanceId: number, newBinding: MidiBinding) => void;
|
onChange: (instanceId: number, newBinding: MidiBinding) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,15 +190,28 @@ const MidiBindingView =
|
|||||||
this.props.onChange(this.props.instanceId, newBinding);
|
this.props.onChange(this.props.instanceId, newBinding);
|
||||||
}
|
}
|
||||||
handleMinChange(value: number): void {
|
handleMinChange(value: number): void {
|
||||||
|
if (!this.props.uiControl) return;
|
||||||
let newBinding = this.props.midiBinding.clone();
|
let newBinding = this.props.midiBinding.clone();
|
||||||
newBinding.minValue = value;
|
newBinding.minValue = this.props.uiControl.valueToRange(value) ;
|
||||||
this.props.onChange(this.props.instanceId, newBinding);
|
this.props.onChange(this.props.instanceId, newBinding);
|
||||||
}
|
}
|
||||||
handleMaxChange(value: number): void {
|
handleMaxChange(value: number): void {
|
||||||
|
if (!this.props.uiControl) return;
|
||||||
let newBinding = this.props.midiBinding.clone();
|
let newBinding = this.props.midiBinding.clone();
|
||||||
newBinding.maxValue = value;
|
newBinding.maxValue = this.props.uiControl.valueToRange(value);
|
||||||
|
console.log(value, newBinding.maxValue)
|
||||||
this.props.onChange(this.props.instanceId, newBinding);
|
this.props.onChange(this.props.instanceId, newBinding);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getDisplayUnit(): string {
|
||||||
|
let control = this.props.uiControl;
|
||||||
|
if (!control) return "";
|
||||||
|
if (control.custom_units !== "") {
|
||||||
|
return control.custom_units.replace("%f", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
return ` ${control.getDisplayUnits()}`
|
||||||
|
}
|
||||||
handleCtlMinChange(value: number): void {
|
handleCtlMinChange(value: number): void {
|
||||||
let newBinding = this.props.midiBinding.clone();
|
let newBinding = this.props.midiBinding.clone();
|
||||||
newBinding.minControlValue = Math.round(value);
|
newBinding.minControlValue = Math.round(value);
|
||||||
@@ -638,21 +653,36 @@ const MidiBindingView =
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
showLinearRange && (
|
showLinearRange && (() => {
|
||||||
|
let uiControl = this.props.uiControl;
|
||||||
|
let displayMin = uiControl ? uiControl.min_value : 0;
|
||||||
|
let displayMax = uiControl ? uiControl.max_value : 1;
|
||||||
|
let unit = this.getDisplayUnit();
|
||||||
|
let isInteger = uiControl?.integer_property ?? false;
|
||||||
|
return (
|
||||||
<div style={{ display: "flex", flexFlow: "row wrap", alignItems: "center" }}>
|
<div style={{ display: "flex", flexFlow: "row wrap", alignItems: "center" }}>
|
||||||
<div className={classes.controlDiv}>
|
<div className={classes.controlDiv}>
|
||||||
<Typography noWrap display="inline">Min Val: </Typography>
|
<Typography noWrap display="inline">Min Val: </Typography>
|
||||||
<NumericInput value={midiBinding.minValue} ariaLabel='min'
|
<NumericInput value={this.props.uiControl?.rangeToValue(midiBinding.minValue) ?? 0} ariaLabel='min'
|
||||||
min={0} max={1} onChange={(value) => { this.handleMinChange(value); }}
|
min={displayMin} max={displayMax} integer={isInteger}
|
||||||
|
onChange={(value) => { this.handleMinChange(value); }}
|
||||||
/>
|
/>
|
||||||
|
{unit !== "" && (
|
||||||
|
<Typography noWrap display="inline"> {unit.trim()}</Typography>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className={classes.controlDiv}>
|
<div className={classes.controlDiv}>
|
||||||
<Typography noWrap display="inline">Max Val: </Typography>
|
<Typography noWrap display="inline">Max Val: </Typography>
|
||||||
<NumericInput value={midiBinding.maxValue} ariaLabel='max'
|
<NumericInput value={this.props.uiControl?.rangeToValue(midiBinding.maxValue) ?? 0} ariaLabel='max'
|
||||||
min={0} max={1} onChange={(value) => { this.handleMaxChange(value); }} />
|
min={displayMin} max={displayMax} integer={isInteger}
|
||||||
|
onChange={(value) => { this.handleMaxChange(value); }} />
|
||||||
|
{unit !== "" && (
|
||||||
|
<Typography noWrap display="inline"> {unit.trim()}</Typography>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
|
})()
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
canRotaryScale && (
|
canRotaryScale && (
|
||||||
|
|||||||
@@ -214,6 +214,7 @@ export const MidiBindingDialog =
|
|||||||
midiControlType={ getMidiControlType(plugin, "__bypass")
|
midiControlType={ getMidiControlType(plugin, "__bypass")
|
||||||
}
|
}
|
||||||
canDoTapTempo={false }
|
canDoTapTempo={false }
|
||||||
|
uiControl={plugin.getControl("__bypass")}
|
||||||
onChange={(instanceId: number, newItem: MidiBinding) => this.handleItemChanged(instanceId, newItem)}
|
onChange={(instanceId: number, newItem: MidiBinding) => this.handleItemChanged(instanceId, newItem)}
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
@@ -258,6 +259,7 @@ export const MidiBindingDialog =
|
|||||||
midiControlType={getMidiControlType(plugin, symbol)}
|
midiControlType={getMidiControlType(plugin, symbol)}
|
||||||
midiBinding={item.getMidiBinding(symbol)}
|
midiBinding={item.getMidiBinding(symbol)}
|
||||||
canDoTapTempo={canDoTapTempo(plugin, symbol)}
|
canDoTapTempo={canDoTapTempo(plugin, symbol)}
|
||||||
|
uiControl={control}
|
||||||
onChange={(instanceId: number, newItem: MidiBinding) => this.handleItemChanged(instanceId, newItem)}
|
onChange={(instanceId: number, newItem: MidiBinding) => this.handleItemChanged(instanceId, newItem)}
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
|
|||||||
@@ -862,7 +862,7 @@ class FilmstripControl implements ModGuiControl {
|
|||||||
console.error("pipedal: Invalid mod-widget-rotation value: " + rotationAttr);
|
console.error("pipedal: Invalid mod-widget-rotation value: " + rotationAttr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let range = this.valueToRange(this.value);
|
let range = this.props.pluginControl.valueToRange(this.value);
|
||||||
this.frameElement.style.transform = `rotate(${rotation * range - rotation / 2}deg)`;
|
this.frameElement.style.transform = `rotate(${rotation * range - rotation / 2}deg)`;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -926,13 +926,13 @@ class FilmstripControl implements ModGuiControl {
|
|||||||
let pluginControl = this.props.pluginControl;
|
let pluginControl = this.props.pluginControl;
|
||||||
|
|
||||||
let value = this.isPointerDown ? this.pointerDownValue : this.value;
|
let value = this.isPointerDown ? this.pointerDownValue : this.value;
|
||||||
value = this.clampValue(value);
|
value = this.props.pluginControl.clampValue(value);
|
||||||
|
|
||||||
let isHorizontalStrip =
|
let isHorizontalStrip =
|
||||||
this.filmstripInfo.frameWidth / this.filmstripInfo.frameHeight
|
this.filmstripInfo.frameWidth / this.filmstripInfo.frameHeight
|
||||||
< this.filmstripInfo.width / this.filmstripInfo.height;
|
< this.filmstripInfo.width / this.filmstripInfo.height;
|
||||||
if (isHorizontalStrip) {
|
if (isHorizontalStrip) {
|
||||||
let range = this.valueToRange(value);
|
let range = this.props.pluginControl.valueToRange(value);
|
||||||
|
|
||||||
if (range < 0) {
|
if (range < 0) {
|
||||||
range = 0;
|
range = 0;
|
||||||
@@ -1045,101 +1045,6 @@ class FilmstripControl implements ModGuiControl {
|
|||||||
this.pointerDownValue = this.value;
|
this.pointerDownValue = this.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
valueToRange(value: number): number {
|
|
||||||
let uiControl = this.props.pluginControl;
|
|
||||||
if (uiControl) {
|
|
||||||
let range: number;
|
|
||||||
if (uiControl.is_logarithmic) {
|
|
||||||
let minValue = uiControl.min_value;
|
|
||||||
if (minValue === 0) // LSP plugins do this.
|
|
||||||
{
|
|
||||||
minValue = 0.0001;
|
|
||||||
}
|
|
||||||
range = Math.log(value / minValue) / Math.log(uiControl.max_value / minValue);
|
|
||||||
if (!isFinite(range)) {
|
|
||||||
if (range < 0) {
|
|
||||||
range = 0;
|
|
||||||
} else {
|
|
||||||
range = 1.0;
|
|
||||||
}
|
|
||||||
} else if (isNaN(range)) {
|
|
||||||
range = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
range = (value - uiControl.min_value) / (uiControl.max_value - uiControl.min_value);
|
|
||||||
if (!isFinite(range)) {
|
|
||||||
if (range < 0) {
|
|
||||||
range = 0;
|
|
||||||
} else {
|
|
||||||
range = 1.0;
|
|
||||||
}
|
|
||||||
} else if (isNaN(range)) {
|
|
||||||
range = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (range > 1) range = 1;
|
|
||||||
if (range < 0) range = 0;
|
|
||||||
return range;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
rangeToValue(range: number): number {
|
|
||||||
if (range < 0) range = 0;
|
|
||||||
if (range > 1) range = 1;
|
|
||||||
let uiControl = this.props.pluginControl;
|
|
||||||
if (uiControl) {
|
|
||||||
let value: number;
|
|
||||||
if (uiControl.min_value === uiControl.max_value) {
|
|
||||||
value = uiControl.min_value;
|
|
||||||
} else {
|
|
||||||
if (uiControl.is_logarithmic) {
|
|
||||||
let minValue = uiControl.min_value;
|
|
||||||
if (minValue === 0) // LSP controls.
|
|
||||||
{
|
|
||||||
minValue = 0.0001;
|
|
||||||
}
|
|
||||||
value = minValue * Math.pow(uiControl.max_value / minValue, range);
|
|
||||||
if (!isFinite(value)) {
|
|
||||||
value = uiControl.max_value;
|
|
||||||
} else if (isNaN(value)) {
|
|
||||||
value = uiControl.min_value;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
value = range * (uiControl.max_value - uiControl.min_value) + uiControl.min_value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
clampValue(value: number): number {
|
|
||||||
let control = this.props.pluginControl;
|
|
||||||
if (control.enumeration_property) {
|
|
||||||
value = control.clampSelectValue(value);
|
|
||||||
} else if (control.toggled_property) {
|
|
||||||
if (value < (control.min_value + control.max_value) / 2) {
|
|
||||||
value = control.min_value;
|
|
||||||
} else {
|
|
||||||
value = control.max_value;
|
|
||||||
}
|
|
||||||
} else if (control.integer_property) {
|
|
||||||
value = Math.round(value);
|
|
||||||
} else if (control.range_steps != 0) {
|
|
||||||
let step = (control.max_value - control.min_value) / control.range_steps;
|
|
||||||
value = Math.round((value - control.min_value) / step) * step + control.min_value;
|
|
||||||
}
|
|
||||||
if (value < control.min_value) {
|
|
||||||
value = control.min_value;
|
|
||||||
}
|
|
||||||
if (value > control.max_value) {
|
|
||||||
value = control.max_value;
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
handlePointerMove(event: PointerEvent) {
|
handlePointerMove(event: PointerEvent) {
|
||||||
if (!this.frameElement) {
|
if (!this.frameElement) {
|
||||||
return; // Not mounted yet
|
return; // Not mounted yet
|
||||||
@@ -1167,14 +1072,14 @@ class FilmstripControl implements ModGuiControl {
|
|||||||
|
|
||||||
let dRange = -dy / rate;
|
let dRange = -dy / rate;
|
||||||
|
|
||||||
let range = this.valueToRange(this.pointerDownValue);
|
let range = this.props.pluginControl.valueToRange(this.pointerDownValue);
|
||||||
range += dRange;
|
range += dRange;
|
||||||
if (range < 0) range = 0;
|
if (range < 0) range = 0;
|
||||||
if (range > 1) range = 1;
|
if (range > 1) range = 1;
|
||||||
let newValue = this.rangeToValue(range);
|
let newValue = this.props.pluginControl.rangeToValue(range);
|
||||||
this.pointerDownValue = newValue;
|
this.pointerDownValue = newValue;
|
||||||
this.setControlValue(newValue);
|
this.setControlValue(newValue);
|
||||||
this.props.onValueChanged(this.props.instanceId, this.props.pluginControl.symbol, this.clampValue(newValue));
|
this.props.onValueChanged(this.props.instanceId, this.props.pluginControl.symbol, this.props.pluginControl.clampValue(newValue));
|
||||||
}
|
}
|
||||||
handlePointerUp(event: PointerEvent) {
|
handlePointerUp(event: PointerEvent) {
|
||||||
let index = this.pointerIds.indexOf(event.pointerId);
|
let index = this.pointerIds.indexOf(event.pointerId);
|
||||||
@@ -1229,11 +1134,11 @@ class FilmstripControl implements ModGuiControl {
|
|||||||
}
|
}
|
||||||
let dRange = event.deltaY / rate;
|
let dRange = event.deltaY / rate;
|
||||||
|
|
||||||
let range = this.valueToRange(this.value);
|
let range = this.props.pluginControl.valueToRange(this.value);
|
||||||
range += dRange;
|
range += dRange;
|
||||||
if (range < 0) range = 0;
|
if (range < 0) range = 0;
|
||||||
if (range > 1) range = 1;
|
if (range > 1) range = 1;
|
||||||
let newValue = this.rangeToValue(range);
|
let newValue = this.props.pluginControl.rangeToValue(range);
|
||||||
this.setControlValue(newValue);
|
this.setControlValue(newValue);
|
||||||
this.props.onValueChanged(this.props.instanceId, this.props.pluginControl.symbol, newValue);
|
this.props.onValueChanged(this.props.instanceId, this.props.pluginControl.symbol, newValue);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
// Copyright (c) Robin E.R. Davies
|
// Copyright (c) 2022 Robin Davies
|
||||||
|
// Copyright (c) Fulgencio Ruiz Rubio.
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
// this software and associated documentation files (the "Software"), to deal in
|
// this software and associated documentation files (the "Software"), to deal in
|
||||||
@@ -203,7 +204,6 @@ const CustomPluginControl =
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
return (<div />);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
@@ -342,8 +342,9 @@ const PluginControl =
|
|||||||
result = this.currentValue; // reset the value!
|
result = this.currentValue; // reset the value!
|
||||||
}
|
}
|
||||||
// clamp and quantize.
|
// clamp and quantize.
|
||||||
let range = this.valueToRange(result);
|
let range = this.props.uiControl?.valueToRange(result) ?? 0;
|
||||||
result = this.rangeToValue(range);
|
result = this.props.uiControl?.rangeToValue(range) ?? 0;
|
||||||
|
|
||||||
let displayVal = this.props.uiControl?.formatShortValue(result) ?? "";
|
let displayVal = this.props.uiControl?.formatShortValue(result) ?? "";
|
||||||
if (event.currentTarget) {
|
if (event.currentTarget) {
|
||||||
event.currentTarget.value = displayVal;
|
event.currentTarget.value = displayVal;
|
||||||
@@ -682,8 +683,8 @@ const PluginControl =
|
|||||||
this.setState({ previewValue: undefined });
|
this.setState({ previewValue: undefined });
|
||||||
}
|
}
|
||||||
previewInputValue(value: number, commitValue: boolean) {
|
previewInputValue(value: number, commitValue: boolean) {
|
||||||
let range = this.valueToRange(value);
|
let range = this.props.uiControl?.valueToRange(value) ?? 0;
|
||||||
value = this.rangeToValue(range);
|
value = this.props.uiControl?.rangeToValue(range) ?? 0;
|
||||||
|
|
||||||
let imgElement = this.imgRef.current
|
let imgElement = this.imgRef.current
|
||||||
if (imgElement) {
|
if (imgElement) {
|
||||||
@@ -712,13 +713,13 @@ const PluginControl =
|
|||||||
|
|
||||||
}
|
}
|
||||||
previewRange(dRange: number, commitValue: boolean): void {
|
previewRange(dRange: number, commitValue: boolean): void {
|
||||||
let range = this.valueToRange(this.currentValue) + dRange;
|
let range = (this.props.uiControl?.valueToRange(this.currentValue) ?? 0) + dRange;
|
||||||
if (range > 1) range = 1;
|
if (range > 1) range = 1;
|
||||||
if (range < 0) range = 0;
|
if (range < 0) range = 0;
|
||||||
let value = this.rangeToValue(range);
|
let value = this.props.uiControl?.rangeToValue(range) ?? 0;
|
||||||
|
|
||||||
// apply value quantization and clipping.
|
// apply value quantization and clipping.
|
||||||
range = this.valueToRange(value);
|
range = this.props.uiControl?.valueToRange(value) ?? 0;
|
||||||
|
|
||||||
if (this.props.uiControl?.isGraphicEq()) {
|
if (this.props.uiControl?.isGraphicEq()) {
|
||||||
let imgElement = this.imgRef.current
|
let imgElement = this.imgRef.current
|
||||||
@@ -835,89 +836,6 @@ const PluginControl =
|
|||||||
if (!uiControl) return "";
|
if (!uiControl) return "";
|
||||||
|
|
||||||
return uiControl.formatDisplayValue(value);
|
return uiControl.formatDisplayValue(value);
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
valueToRange(value: number): number {
|
|
||||||
let uiControl = this.props.uiControl;
|
|
||||||
if (uiControl) {
|
|
||||||
if (uiControl.integer_property) {
|
|
||||||
value = Math.round(value);
|
|
||||||
}
|
|
||||||
let range: number;
|
|
||||||
if (uiControl.is_logarithmic) {
|
|
||||||
let minValue = uiControl.min_value;
|
|
||||||
if (minValue === 0) // LSP plugins do this.
|
|
||||||
{
|
|
||||||
minValue = 0.0001;
|
|
||||||
}
|
|
||||||
range = Math.log(value / minValue) / Math.log(uiControl.max_value / minValue);
|
|
||||||
if (!isFinite(range)) {
|
|
||||||
if (range < 0) {
|
|
||||||
range = 0;
|
|
||||||
} else {
|
|
||||||
range = 1.0;
|
|
||||||
}
|
|
||||||
} else if (isNaN(range)) {
|
|
||||||
range = 0;
|
|
||||||
}
|
|
||||||
if (uiControl.range_steps > 1) {
|
|
||||||
range = Math.round(range * (uiControl.range_steps - 1)) / (uiControl.range_steps - 1);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
range = (value - uiControl.min_value) / (uiControl.max_value - uiControl.min_value);
|
|
||||||
if (!isFinite(range)) {
|
|
||||||
if (range < 0) {
|
|
||||||
range = 0;
|
|
||||||
} else {
|
|
||||||
range = 1.0;
|
|
||||||
}
|
|
||||||
} else if (isNaN(range)) {
|
|
||||||
range = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (range > 1) range = 1;
|
|
||||||
if (range < 0) range = 0;
|
|
||||||
return range;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
rangeToValue(range: number): number {
|
|
||||||
if (range < 0) range = 0;
|
|
||||||
if (range > 1) range = 1;
|
|
||||||
let uiControl = this.props.uiControl;
|
|
||||||
if (uiControl) {
|
|
||||||
if (uiControl.range_steps > 1) {
|
|
||||||
range = Math.round(range * (uiControl.range_steps - 1)) / (uiControl.range_steps - 1);
|
|
||||||
}
|
|
||||||
let value: number;
|
|
||||||
if (uiControl.min_value === uiControl.max_value) {
|
|
||||||
value = uiControl.min_value;
|
|
||||||
} else {
|
|
||||||
if (uiControl.is_logarithmic) {
|
|
||||||
let minValue = uiControl.min_value;
|
|
||||||
if (minValue === 0) // LSP controls.
|
|
||||||
{
|
|
||||||
minValue = 0.0001;
|
|
||||||
}
|
|
||||||
value = minValue * Math.pow(uiControl.max_value / minValue, range);
|
|
||||||
if (!isFinite(value)) {
|
|
||||||
value = uiControl.max_value;
|
|
||||||
} else if (isNaN(value)) {
|
|
||||||
value = uiControl.min_value;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
value = range * (uiControl.max_value - uiControl.min_value) + uiControl.min_value;
|
|
||||||
}
|
|
||||||
if (uiControl.integer_property) {
|
|
||||||
value = Math.round(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rangeToRotationTransform(range: number): string {
|
rangeToRotationTransform(range: number): string {
|
||||||
@@ -926,22 +844,10 @@ const PluginControl =
|
|||||||
}
|
}
|
||||||
|
|
||||||
getEqPosition(): number {
|
getEqPosition(): number {
|
||||||
let range = 0;
|
return this.props.uiControl?.valueToRange(this.props.value) ?? 0;
|
||||||
let uiControl = this.props.uiControl;
|
|
||||||
if (uiControl) {
|
|
||||||
let value = this.props.value;
|
|
||||||
range = this.valueToRange(value);
|
|
||||||
}
|
|
||||||
return range;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
getRotationTransform(): string {
|
getRotationTransform(): string {
|
||||||
let range = 0;
|
let range = this.props.uiControl?.valueToRange(this.props.value) ?? 0;
|
||||||
let uiControl = this.props.uiControl;
|
|
||||||
if (uiControl) {
|
|
||||||
let value = this.props.value;
|
|
||||||
range = this.valueToRange(value);
|
|
||||||
}
|
|
||||||
return this.rangeToRotationTransform(range);
|
return this.rangeToRotationTransform(range);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user