/* * MIT License * * Copyright (c) 2023 Robin E. R. Davies * * 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 * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is furnished to do * so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ import React, { Component, SyntheticEvent } from 'react'; import { Theme } from '@mui/material/styles'; import { WithStyles } from '@mui/styles'; import createStyles from '@mui/styles/createStyles'; import withStyles from '@mui/styles/withStyles'; import { PiPedalFileProperty } from './Lv2Plugin'; import Typography from '@mui/material/Typography'; import { PiPedalModel, PiPedalModelFactory, ListenHandle, StateChangedHandle } from './PiPedalModel'; import ButtonBase from '@mui/material/ButtonBase' import MoreHorizIcon from '@mui/icons-material/MoreHoriz'; export const StandardItemSize = { width: 80, height: 140 } const styles = (theme: Theme) => createStyles({ frame: { position: "relative", margin: "12px" }, switchTrack: { height: '100%', width: '100%', borderRadius: 14 / 2, zIndex: -1, transition: theme.transitions.create(['opacity', 'background-color'], { duration: theme.transitions.duration.shortest }), backgroundColor: theme.palette.secondary.main, opacity: theme.palette.mode === 'light' ? 0.38 : 0.3 }, displayValue: { position: "absolute", top: 0, left: 0, right: 0, bottom: 4, textAlign: "center", background: "white", color: "#666", // zIndex: -1, } }); export interface FilePropertyControlProps extends WithStyles { instanceId: number; fileProperty: PiPedalFileProperty; onFileClick: (fileProperty: PiPedalFileProperty, value: string) => void; theme: Theme; } type FilePropertyControlState = { error: boolean; value: string; }; const FilePropertyControl = withStyles(styles, { withTheme: true })( class extends Component { model: PiPedalModel; constructor(props: FilePropertyControlProps) { super(props); this.state = { error: false, value: "", }; this.model = PiPedalModelFactory.getInstance(); if (this.props.fileProperty.patchProperty !== "") { this.subscribeToPropertyGet(); } } private propertyGetHandle?: ListenHandle; refreshPatchProperty() { this.model.getPatchProperty(this.props.instanceId, this.props.fileProperty.patchProperty) .then( (json: any) => { if (json && json.otype_ === "Path") { let path = json.value as string; this.setState({ value: path }); } } ) .catch( (error: Error) => { this.model.showAlert(error.toString()); } ); } stateChangedHandle?: StateChangedHandle; subscribeToPropertyGet() { // this.propertyGetHandle = this.model.listenForAtomOutput(this.props.instanceId,(instanceId,atomOutput)=>{ // // PARSE THE OBJECT! // // this.setState({value: atomOutput?.value as string}); // }); if (this.stateChangedHandle) { this.model.removeLv2StateChangedListener(this.stateChangedHandle); } this.refreshPatchProperty(); this.stateChangedHandle = this.model.addLv2StateChangedListener( this.props.instanceId, () => { this.refreshPatchProperty(); }); } unsubscribeToPropertyGet() { if (this.stateChangedHandle) { this.model.removeLv2StateChangedListener(this.stateChangedHandle); } } componentDidMount() { this.subscribeToPropertyGet(); } componentWillUnmount() { this.unsubscribeToPropertyGet(); } componentDidUpdate(prevProps: Readonly, prevState: Readonly, snapshot?: any): void { if (prevProps.fileProperty.patchProperty !== this.props.fileProperty.patchProperty || prevProps.instanceId !== this.props.instanceId) { this.setState({ value: "" }); this.unsubscribeToPropertyGet(); this.subscribeToPropertyGet(); } } inputChanged: boolean = false; onDrag(e: SyntheticEvent) { e.preventDefault(); } onFileClick() { this.props.onFileClick(this.props.fileProperty, this.state.value); } private fileNameOnly(path: string): string { let slashPos = path.lastIndexOf('/'); if (slashPos < 0) { slashPos = 0; } else { ++slashPos; } let extPos = path.lastIndexOf('.'); if (extPos < 0 || extPos < slashPos) { extPos = path.length; } return path.substring(slashPos, extPos); } render() { //let classes = this.props.classes; let fileProperty = this.props.fileProperty; let value = this.fileNameOnly(this.state.value); if (!value || value.length === 0) { value = "\u00A0"; } let item_width = 264; return (
{/* TITLE SECTION */}
{fileProperty.label}
{/* CONTROL SECTION */}
{ this.onFileClick() }} >
{value}
 
{/* LABEL/EDIT SECTION*/}
); } } ); export default FilePropertyControl;