"use client"; import { Box, Button, ButtonGroup, Grid, Input, Slider, Stack, TextField, } from "@mui/material"; import React from "react"; import { StripBusOutput, StripBusOutputEvent } from "./StripBusOutput"; import { EventCounter } from "@/utils/EventCounter"; export interface StripProps { physicalBuses: number; virtualBuses: number; values?: Partial; showOutputdB?: boolean; name: string; onChange: (event: StripEvent) => any; } type StateDefaultValueException = "showOutputdB"; export interface StripState { gain: number; outputBuses: boolean[]; muted: boolean; showOutputdB: 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 { private defaultValues: Omit; private eventCounter = new EventCounter<"onSliderResetDefaults">(); constructor(props: StripProps) { super(props); const { values: initialValues } = props; this.defaultValues = { gain: 0, outputBuses: [...Array(props.physicalBuses + props.virtualBuses)].map( (_v, k) => false ), muted: false, }; const getValue = (name: keyof typeof this.defaultValues) => { if (initialValues === undefined) return this.defaultValues[name]; return initialValues[name] !== undefined ? this.defaultValues[name] : initialValues[name]; }; this.state = { ...(Object.fromEntries( Object.entries(this.defaultValues).map(([name]) => [ name, getValue(name as keyof typeof this.defaultValues) as any, ]) ) as Omit), showOutputdB: props.showOutputdB !== undefined ? props.showOutputdB : true, }; this.eventCounter.on({ callback: this.onResetDefaults.bind(this), count: 2, name: "onSliderResetDefaults", }); } onResetDefaults() { this.setState({ gain: this.defaultValues.gain }); } onSliderClick(event: React.MouseEvent) { this.stopPropagation(event); this.eventCounter.emit("onSliderResetDefaults"); } onKeyDown(event: React.KeyboardEvent) { console.log(event); if (event.key === "ArrowLeft" || event.key === "ArrowRight") { event.preventDefault(); } } onGainChange(event: Event) { this.stopPropagation(event); 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.outputBuses; buses[ event.isVirtual ? this.props.physicalBuses + event.busId : event.busId ] = event.enabled; this.setState({ outputBuses: buses, }); this.props.onChange({ type: "StripBusOutputChanged", busId: event.busId, isVirtual: event.isVirtual, enabled: event.enabled, }); } onStripWheel(event: React.WheelEvent) { console.log(event); } onMuteToggle(event: React.MouseEvent) { this.stopPropagation(event); this.setState( (state) => ({ muted: !state.muted }), () => { this.props.onChange({ type: "StripMuted", muted: this.state.muted }); } ); } stopPropagation(event: Event | React.MouseEvent) { if (event instanceof Event) event.stopImmediatePropagation(); else event.nativeEvent.stopImmediatePropagation(); } render() { return ( <> this.onStripWheel(e)} onClick={(e) => this.stopPropagation(e)} size="small" type="number" label={this.props.name} // sx={{minWidth: "4em", maxWidth: "5em"}} // fullWidth /> 0 && this.state.gain < 12 && "warning") || (this.state.gain >= 12 && "error") || (this.state.gain < 0 && "info") || "primary" } orientation="vertical" defaultValue={0.0} step={0.1} min={-60} max={12} value={this.state.gain} aria-label="Temperature" onChange={(e) => this.onGainChange(e)} onClick={(e) => this.onSliderClick(e)} /> {[ ...Array(this.props.physicalBuses + this.props.virtualBuses), ].map((_v, i) => ( this.onBusChange(e)} default={{ enabled: this.state.outputBuses[i] }} /> ))} ); } }