2024-07-22 01:41:17 +02:00
|
|
|
"use client";
|
2024-08-06 02:51:59 +02:00
|
|
|
import {
|
|
|
|
Box,
|
|
|
|
Button,
|
|
|
|
ButtonGroup,
|
|
|
|
Grid,
|
|
|
|
Input,
|
|
|
|
Slider,
|
|
|
|
Stack,
|
2024-08-07 23:34:13 +02:00
|
|
|
TextField,
|
2024-08-08 00:33:48 +02:00
|
|
|
Typography,
|
2024-08-06 02:51:59 +02:00
|
|
|
} from "@mui/material";
|
2024-07-22 01:41:17 +02:00
|
|
|
import React from "react";
|
|
|
|
import { StripBusOutput, StripBusOutputEvent } from "./StripBusOutput";
|
2024-08-07 21:39:58 +02:00
|
|
|
import { EventCounter } from "@/utils/EventCounter";
|
2024-07-22 01:41:17 +02:00
|
|
|
|
|
|
|
export interface StripProps {
|
|
|
|
physicalBuses: number;
|
|
|
|
virtualBuses: number;
|
2024-08-06 02:51:59 +02:00
|
|
|
values?: Partial<StripState>;
|
2024-08-08 00:33:48 +02:00
|
|
|
width: number;
|
2024-08-07 23:34:13 +02:00
|
|
|
name: string;
|
2024-07-30 02:39:44 +02:00
|
|
|
onChange: (event: StripEvent) => any;
|
2024-07-22 01:41:17 +02:00
|
|
|
}
|
2024-08-08 00:33:48 +02:00
|
|
|
|
|
|
|
export type StateDefaultValueException = "";
|
2024-07-22 01:41:17 +02:00
|
|
|
|
|
|
|
export interface StripState {
|
|
|
|
gain: number;
|
2024-08-06 02:51:59 +02:00
|
|
|
outputBuses: boolean[];
|
2024-07-22 01:41:17 +02:00
|
|
|
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> {
|
2024-08-07 23:34:13 +02:00
|
|
|
private defaultValues: Omit<StripState, StateDefaultValueException>;
|
2024-08-07 21:39:58 +02:00
|
|
|
private eventCounter = new EventCounter<"onSliderResetDefaults">();
|
2024-07-22 01:41:17 +02:00
|
|
|
constructor(props: StripProps) {
|
|
|
|
super(props);
|
2024-08-06 02:51:59 +02:00
|
|
|
const { values: initialValues } = props;
|
2024-08-07 21:39:58 +02:00
|
|
|
this.defaultValues = {
|
2024-08-06 02:51:59 +02:00
|
|
|
gain: 0,
|
|
|
|
outputBuses: [...Array(props.physicalBuses + props.virtualBuses)].map(
|
|
|
|
(_v, k) => false
|
2024-07-22 01:41:17 +02:00
|
|
|
),
|
2024-08-06 02:51:59 +02:00
|
|
|
muted: false,
|
2024-07-22 01:41:17 +02:00
|
|
|
};
|
2024-08-07 21:39:58 +02:00
|
|
|
const getValue = (name: keyof typeof this.defaultValues) => {
|
|
|
|
if (initialValues === undefined) return this.defaultValues[name];
|
2024-08-06 02:51:59 +02:00
|
|
|
return initialValues[name] !== undefined
|
2024-08-07 21:39:58 +02:00
|
|
|
? this.defaultValues[name]
|
2024-08-06 02:51:59 +02:00
|
|
|
: initialValues[name];
|
|
|
|
};
|
2024-08-07 23:34:13 +02:00
|
|
|
this.state = {
|
|
|
|
...(Object.fromEntries(
|
|
|
|
Object.entries(this.defaultValues).map(([name]) => [
|
|
|
|
name,
|
|
|
|
getValue(name as keyof typeof this.defaultValues) as any,
|
|
|
|
])
|
|
|
|
) as Omit<StripState, StateDefaultValueException>),
|
|
|
|
};
|
2024-08-07 21:39:58 +02:00
|
|
|
this.eventCounter.on({
|
|
|
|
callback: this.onResetDefaults.bind(this),
|
|
|
|
count: 2,
|
|
|
|
name: "onSliderResetDefaults",
|
|
|
|
});
|
|
|
|
}
|
|
|
|
onResetDefaults() {
|
|
|
|
this.setState({ gain: this.defaultValues.gain });
|
2024-08-06 02:51:59 +02:00
|
|
|
}
|
2024-08-07 21:39:58 +02:00
|
|
|
onSliderClick(event: React.MouseEvent) {
|
|
|
|
this.stopPropagation(event);
|
|
|
|
this.eventCounter.emit("onSliderResetDefaults");
|
2024-07-22 01:41:17 +02:00
|
|
|
}
|
|
|
|
onKeyDown(event: React.KeyboardEvent) {
|
2024-07-30 02:39:44 +02:00
|
|
|
console.log(event);
|
2024-08-06 02:51:59 +02:00
|
|
|
|
2024-07-22 01:41:17 +02:00
|
|
|
if (event.key === "ArrowLeft" || event.key === "ArrowRight") {
|
|
|
|
event.preventDefault();
|
|
|
|
}
|
|
|
|
}
|
2024-08-07 21:39:58 +02:00
|
|
|
onGainChange(event: Event) {
|
|
|
|
this.stopPropagation(event);
|
2024-07-22 01:41:17 +02:00
|
|
|
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) {
|
2024-08-06 02:51:59 +02:00
|
|
|
const buses = this.state.outputBuses;
|
2024-07-22 01:41:17 +02:00
|
|
|
buses[
|
|
|
|
event.isVirtual ? this.props.physicalBuses + event.busId : event.busId
|
|
|
|
] = event.enabled;
|
|
|
|
this.setState({
|
2024-08-06 02:51:59 +02:00
|
|
|
outputBuses: buses,
|
2024-07-22 01:41:17 +02:00
|
|
|
});
|
|
|
|
this.props.onChange({
|
|
|
|
type: "StripBusOutputChanged",
|
|
|
|
busId: event.busId,
|
|
|
|
isVirtual: event.isVirtual,
|
|
|
|
enabled: event.enabled,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
onStripWheel(event: React.WheelEvent) {
|
|
|
|
console.log(event);
|
|
|
|
}
|
2024-08-07 21:39:58 +02:00
|
|
|
onMuteToggle(event: React.MouseEvent) {
|
|
|
|
this.stopPropagation(event);
|
2024-07-22 01:41:17 +02:00
|
|
|
this.setState(
|
|
|
|
(state) => ({ muted: !state.muted }),
|
|
|
|
() => {
|
|
|
|
this.props.onChange({ type: "StripMuted", muted: this.state.muted });
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
2024-08-07 21:39:58 +02:00
|
|
|
stopPropagation(event: Event | React.MouseEvent) {
|
|
|
|
if (event instanceof Event) event.stopImmediatePropagation();
|
|
|
|
else event.nativeEvent.stopImmediatePropagation();
|
|
|
|
}
|
2024-07-22 01:41:17 +02:00
|
|
|
render() {
|
|
|
|
return (
|
|
|
|
<>
|
2024-08-08 00:33:48 +02:00
|
|
|
<Stack
|
|
|
|
direction={"row"}
|
|
|
|
sx={{
|
|
|
|
...(this.props.width <= 1027 && { marginBlockEnd: "10px" }),
|
|
|
|
}}
|
|
|
|
>
|
2024-08-07 23:34:13 +02:00
|
|
|
<Stack alignItems={"center"} style={{ maxWidth: "70px" }}>
|
2024-08-08 00:33:48 +02:00
|
|
|
{this.props.width > 600 ? (
|
|
|
|
<TextField
|
|
|
|
// inputProps={{
|
|
|
|
// "aria-labelledby": "input-slider",
|
|
|
|
// itemType: "number",
|
|
|
|
// style: { padding: 0 },
|
|
|
|
// }}
|
|
|
|
value={this.state.gain}
|
|
|
|
onWheel={(e) => this.onStripWheel(e)}
|
|
|
|
onClick={(e) => this.stopPropagation(e)}
|
|
|
|
size="small"
|
|
|
|
type="number"
|
|
|
|
label={this.props.name}
|
|
|
|
// sx={{minWidth: "4em", maxWidth: "5em"}}
|
|
|
|
// fullWidth
|
|
|
|
/>
|
|
|
|
) : (
|
|
|
|
<>
|
|
|
|
<Typography variant="caption">{this.props.name}</Typography>
|
|
|
|
<Typography width={"4em"} textAlign="center" variant="caption">
|
|
|
|
{this.state.gain} dB
|
|
|
|
</Typography>
|
|
|
|
</>
|
|
|
|
)}
|
2024-07-22 01:41:17 +02:00
|
|
|
<Slider
|
|
|
|
sx={{
|
2024-08-08 00:33:48 +02:00
|
|
|
// margin: "5px",
|
|
|
|
marginBlockStart: "10px",
|
2024-07-22 01:41:17 +02:00
|
|
|
}}
|
2024-08-07 21:39:58 +02:00
|
|
|
color={
|
|
|
|
(this.state.gain > 0 && this.state.gain < 12 && "warning") ||
|
|
|
|
(this.state.gain >= 12 && "error") ||
|
|
|
|
(this.state.gain < 0 && "info") ||
|
|
|
|
"primary"
|
|
|
|
}
|
2024-07-22 01:41:17 +02:00
|
|
|
orientation="vertical"
|
|
|
|
defaultValue={0.0}
|
|
|
|
step={0.1}
|
|
|
|
min={-60}
|
|
|
|
max={12}
|
|
|
|
value={this.state.gain}
|
|
|
|
aria-label="Temperature"
|
2024-08-07 21:39:58 +02:00
|
|
|
onChange={(e) => this.onGainChange(e)}
|
|
|
|
onClick={(e) => this.onSliderClick(e)}
|
2024-07-22 01:41:17 +02:00
|
|
|
/>
|
|
|
|
</Stack>
|
|
|
|
<Stack>
|
2024-08-07 23:34:13 +02:00
|
|
|
<ButtonGroup orientation="vertical">
|
2024-07-22 01:41:17 +02:00
|
|
|
{[
|
|
|
|
...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}
|
2024-08-07 21:39:58 +02:00
|
|
|
onChange={(e) => this.onBusChange(e)}
|
2024-08-06 02:51:59 +02:00
|
|
|
default={{ enabled: this.state.outputBuses[i] }}
|
2024-07-22 01:41:17 +02:00
|
|
|
/>
|
|
|
|
))}
|
2024-08-07 21:39:58 +02:00
|
|
|
<Button
|
|
|
|
onClick={(e) => this.onMuteToggle(e)}
|
|
|
|
variant={this.state.muted ? "contained" : "outlined"}
|
|
|
|
color={"error"}
|
|
|
|
size="small"
|
|
|
|
>
|
|
|
|
Mute
|
|
|
|
</Button>
|
2024-07-22 01:41:17 +02:00
|
|
|
</ButtonGroup>
|
|
|
|
</Stack>
|
2024-08-06 02:51:59 +02:00
|
|
|
</Stack>
|
2024-07-22 01:41:17 +02:00
|
|
|
</>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|