Merge pull request #486 from FoolHen/midi-unit-range
Add units to MIDI range control
This commit is contained in:
@@ -25,7 +25,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 +96,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,14 +190,53 @@ const MidiBindingView =
|
|||||||
}
|
}
|
||||||
handleMinChange(value: number): void {
|
handleMinChange(value: number): void {
|
||||||
let newBinding = this.props.midiBinding.clone();
|
let newBinding = this.props.midiBinding.clone();
|
||||||
newBinding.minValue = value;
|
newBinding.minValue = this.realToMidi(value);
|
||||||
this.props.onChange(this.props.instanceId, newBinding);
|
this.props.onChange(this.props.instanceId, newBinding);
|
||||||
}
|
}
|
||||||
handleMaxChange(value: number): void {
|
handleMaxChange(value: number): void {
|
||||||
let newBinding = this.props.midiBinding.clone();
|
let newBinding = this.props.midiBinding.clone();
|
||||||
newBinding.maxValue = value;
|
newBinding.maxValue = this.realToMidi(value);
|
||||||
this.props.onChange(this.props.instanceId, newBinding);
|
this.props.onChange(this.props.instanceId, newBinding);
|
||||||
}
|
}
|
||||||
|
private realToMidi(realValue: number): number {
|
||||||
|
let control = this.props.uiControl;
|
||||||
|
if (!control) return realValue;
|
||||||
|
let range = control.max_value - control.min_value;
|
||||||
|
if (range === 0) return 0;
|
||||||
|
return (realValue - control.min_value) / range;
|
||||||
|
}
|
||||||
|
private midiToReal(midiValue: number): number {
|
||||||
|
let control = this.props.uiControl;
|
||||||
|
if (!control) return midiValue;
|
||||||
|
return midiValue * (control.max_value - control.min_value) + control.min_value;
|
||||||
|
}
|
||||||
|
private getDisplayUnit(): string {
|
||||||
|
let control = this.props.uiControl;
|
||||||
|
if (!control) return "";
|
||||||
|
if (control.custom_units !== "") {
|
||||||
|
return control.custom_units.replace("%f", "");
|
||||||
|
}
|
||||||
|
switch (control.units) {
|
||||||
|
case "bar": return " bar";
|
||||||
|
case "beat": return " beats";
|
||||||
|
case "bpm": return " bpm";
|
||||||
|
case "cent": return " cents";
|
||||||
|
case "cm": return " cm";
|
||||||
|
case "db": return " dB";
|
||||||
|
case "hz": return " Hz";
|
||||||
|
case "khz": return " kHz";
|
||||||
|
case "km": return " km";
|
||||||
|
case "m": return " m";
|
||||||
|
case "mhz": return " MHz";
|
||||||
|
case "midiNote": return "MIDI note";
|
||||||
|
case "min": return " min";
|
||||||
|
case "ms": return " ms";
|
||||||
|
case "pc": return " %";
|
||||||
|
case "s": return " s";
|
||||||
|
case "semitone12TET": return " st";
|
||||||
|
default: return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
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 +678,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.midiToReal(midiBinding.minValue)} 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.midiToReal(midiBinding.maxValue)} 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>
|
||||||
|
|||||||
Reference in New Issue
Block a user