Voicemeeter-remote-frontend/src/app/component/Strip.tsx
2024-07-22 01:41:17 +02:00

172 lines
4.8 KiB
TypeScript

"use client";
import { Button, ButtonGroup, Grid, Input, Slider, Stack } from "@mui/material";
import React from "react";
import { StripBusOutput, StripBusOutputEvent } from "./StripBusOutput";
export interface StripProps {
physicalBuses: number;
virtualBuses: number;
default?: Partial<StripState>;
onChange: <T extends StripEvent>(event: StripEvent) => any;
}
export interface StripState {
gain: number;
buses: boolean[];
muted: boolean;
}
export type StripEvent = StripBusOutputChanged | StripMuted | StripGainChanged;
export interface StripBusOutputChanged extends StripBusOutputEvent {
type: "StripBusOutputChanged";
}
export interface StripGainChanged {
type: "StripGainChanged";
gain: number;
}
export interface StripMuted {
type: "StripMuted";
muted: boolean;
}
export class Strip extends React.Component<StripProps, StripState> {
constructor(props: StripProps) {
super(props);
const buses = (props.default && props.default.buses) || [];
this.state = {
gain:
props.default && props.default.gain !== undefined
? props.default.gain
: 0,
buses: [...Array(props.physicalBuses + props.virtualBuses)].map((_v, k) =>
buses[k] === undefined ? false : buses[k]
),
muted:
props.default && props.default.muted !== undefined
? props.default.muted
: false,
};
}
onKeyDown(event: React.KeyboardEvent) {
if (event.key === "ArrowLeft" || event.key === "ArrowRight") {
event.preventDefault();
}
}
onChange(event: React.ChangeEvent<HTMLInputElement>) {
const multiplier = (event as unknown as React.KeyboardEvent).shiftKey
? 2
: 1;
const changedGain =
parseFloat((event.target as HTMLInputElement).value) * multiplier;
this.setState({
gain: changedGain,
});
this.props.onChange({
type: "StripGainChanged",
gain: changedGain,
});
}
onBusChange(event: StripBusOutputEvent) {
const buses = this.state.buses;
buses[
event.isVirtual ? this.props.physicalBuses + event.busId : event.busId
] = event.enabled;
this.setState({
buses,
});
this.props.onChange({
type: "StripBusOutputChanged",
busId: event.busId,
isVirtual: event.isVirtual,
enabled: event.enabled,
});
}
onStripWheel(event: React.WheelEvent) {
console.log(event);
}
onMuteToggle() {
this.setState(
(state) => ({ muted: !state.muted }),
() => {
this.props.onChange({ type: "StripMuted", muted: this.state.muted });
}
);
}
render() {
return (
<>
<Grid container>
<Stack alignItems={"center"}>
<Input
inputProps={{
"aria-labelledby": "input-slider",
itemType: "number",
}}
value={this.state.gain}
onWheel={(ev) => this.onStripWheel(ev)}
size="small"
sx={{ width: "50px" }}
/>
<Slider
sx={{
margin: "5px",
// minHeight: "30%",
'& input[type="range"]': {
WebkitAppearance: "slider-vertical",
},
}}
orientation="vertical"
defaultValue={0.0}
step={0.1}
min={-60}
max={12}
value={this.state.gain}
aria-label="Temperature"
onChange={(ev) =>
this.onChange(
ev as unknown as React.ChangeEvent<HTMLInputElement>
)
}
onKeyDown={(ev) => this.onKeyDown(ev)}
/>
<Button
onClick={() => this.onMuteToggle()}
variant={this.state.muted ? "contained" : "outlined"}
color={"error"}
>
Mute
</Button>
</Stack>
<Stack>
<ButtonGroup orientation="vertical">
{[
...Array(this.props.physicalBuses + this.props.virtualBuses),
].map((_v, i) => (
<StripBusOutput
key={`${i < this.props.physicalBuses ? "a" : "b"}${
i < this.props.physicalBuses
? i
: i - this.props.physicalBuses
}`}
id={
i < this.props.physicalBuses
? i
: i - this.props.physicalBuses
}
isVirtual={i < this.props.physicalBuses ? false : true}
onChange={(ev) => this.onBusChange(ev)}
default={{ enabled: this.state.buses[i] }}
/>
))}
</ButtonGroup>
</Stack>
</Grid>
</>
);
}
}