// Copyright (c) 2022 Robin 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 { SyntheticEvent, Component } from 'react'; import IconButton from '@mui/material/IconButton'; import Typography from '@mui/material/Typography'; import { PiPedalModel, PiPedalModelFactory, PresetIndex } from './PiPedalModel'; import SaveIconOutline from '@mui/icons-material/Save'; import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown"; import ButtonBase from "@mui/material/ButtonBase"; import MoreVertIcon from '@mui/icons-material/MoreVert'; import { Theme } from '@mui/material/styles'; import { WithStyles } from '@mui/styles'; import withStyles from '@mui/styles/withStyles'; import createStyles from '@mui/styles/createStyles'; import PresetDialog from './PresetDialog'; import Menu from '@mui/material/Menu'; import MenuItem from '@mui/material/MenuItem'; import Fade from '@mui/material/Fade'; import Divider from '@mui/material/Divider'; import RenameDialog from './RenameDialog' import Select from '@mui/material/Select'; import UploadPresetDialog from './UploadPresetDialog'; interface PresetSelectorProps extends WithStyles { } interface PresetSelectorState { presets: PresetIndex; enabled: boolean; showPresetsDialog: boolean; showEditPresetsDialog: boolean; presetsMenuAnchorRef: HTMLElement | null; renameDialogOpen: boolean; renameDialogDefaultName: string; renameDialogActionName: string; renameDialogOnOk?: (name: string) => void; openUploadPresetDialog: boolean; } const selectColor = "black"; const styles = (theme: Theme) => createStyles({ select: { // fu fu fu.Overrides for white selector on dark background. '&:before': { borderColor: selectColor, }, '&:after': { borderColor: selectColor, }, '&:hover:not(.Mui-disabled):before': { borderColor: selectColor, } }, icon: { fill: selectColor, }, }); const PresetSelector = withStyles(styles, { withTheme: true })( class extends Component { model: PiPedalModel; constructor(props: PresetSelectorProps) { super(props); this.model = PiPedalModelFactory.getInstance(); this.state = { presets: this.model.presets.get(), enabled: false, showPresetsDialog: false, showEditPresetsDialog: false, presetsMenuAnchorRef: null, renameDialogOpen: false, renameDialogDefaultName: "", renameDialogActionName: "", renameDialogOnOk: undefined, openUploadPresetDialog: false }; this.handlePresetsChanged = this.handlePresetsChanged.bind(this); this.handleDialogClose = this.handleDialogClose.bind(this); this.handlePresetsMenuClose = this.handlePresetsMenuClose.bind(this); } handlePresetMenuClick(event: SyntheticEvent): void { this.setState({ presetsMenuAnchorRef: (event.currentTarget as HTMLElement) }); } handlePresetsMenuClose(): void { this.setState({ presetsMenuAnchorRef: null }); } handleDownloadPreset(e: SyntheticEvent) { this.handlePresetsMenuClose(); e.preventDefault(); this.model.download("downloadPreset", this.model.presets.get().selectedInstanceId); } handleUploadPreset(e: SyntheticEvent) { this.handlePresetsMenuClose(); e.preventDefault(); this.setState({ openUploadPresetDialog: true }); } handlePresetsMenuSave(e: SyntheticEvent): void { this.handlePresetsMenuClose(); e.preventDefault(); this.model.saveCurrentPreset(); } handlePresetsMenuSaveAs(e: SyntheticEvent): void { this.handlePresetsMenuClose(); e.stopPropagation(); let currentPresets = this.model.presets.get(); let item = currentPresets.getItem(currentPresets.selectedInstanceId); if (item == null) return; let name = item.name; this.renameDialogOpen(name, "Save As") .then((newName) => { return this.model.saveCurrentPresetAs(newName); }) .then((newInstanceId) => { }) .catch((error) => { this.showError(error); }) ; } handlePresetsMenuRename(e: SyntheticEvent): void { this.handlePresetsMenuClose(); e.stopPropagation(); let currentPresets = this.model.presets.get(); let item = currentPresets.getItem(currentPresets.selectedInstanceId); if (item == null) return; let name = item.name; this.renameDialogOpen(name, "Rename") .then((newName) => { if (newName === name) return; return this.model.renamePresetItem(this.model.presets.get().selectedInstanceId, newName); }) .catch((error) => { this.showError(error); }) ; } handlePresetsMenuNew(e: SyntheticEvent): void { this.handlePresetsMenuClose(); e.stopPropagation(); let currentPresets = this.model.presets.get(); let item = currentPresets.getItem(currentPresets.selectedInstanceId); if (item == null) return; this.model.newPresetItem(currentPresets.selectedInstanceId) .then((instanceId) => { this.model.loadPreset(instanceId); }) .catch((error) => { this.showError(error); }); } showError(error: string) { this.model.showAlert(error); } renameDialogOpen(defaultText: string, acceptButtonText: string): Promise { let result = new Promise( (resolve, reject) => { this.setState( { renameDialogOpen: true, renameDialogDefaultName: defaultText, renameDialogActionName: acceptButtonText, renameDialogOnOk: (name) => { resolve(name); } } ); } ); return result; } handleRenameDialogClose(): void { this.setState({ renameDialogOpen: false, renameDialogOnOk: undefined }); } handleRenameDialogOk(name: string): void { let renameDialogOnOk = this.state.renameDialogOnOk; this.handleRenameDialogClose(); if (renameDialogOnOk) { renameDialogOnOk(name); } } handleMenuEditPresets(): void { this.handlePresetsMenuClose(); this.showEditPresetsDialog(true); } updatePresetState() { let presets = this.model.presets.get(); let enabled = presets.presets.length > 0 && presets.selectedInstanceId !== -1; this.setState( { presets: presets, enabled: enabled, } ); } handleSave() { this.model.saveCurrentPreset(); } handlePresetsChanged() { this.updatePresetState(); } componentDidMount() { this.model.presets.addOnChangedHandler(this.handlePresetsChanged); this.updatePresetState(); } componentWillUnmount() { this.model.presets.removeOnChangedHandler(this.handlePresetsChanged) } showPresetDialog(show: boolean) { this.setState({ showPresetsDialog: show, showEditPresetsDialog: false }); } showEditPresetsDialog(show: boolean) { this.setState({ showPresetsDialog: show, showEditPresetsDialog: true }); } handleDialogClose(): void { this.showPresetDialog(false); } handleChange(event: any, extra: any): void { // misses click on default. // this.model.loadPreset(event.target.value as number); } handleSelectClose(event: any): void { let value = event.currentTarget.getAttribute("data-value"); if (value && value.length > 0) { this.model.loadPreset(parseInt(value)); } //this.model.loadPreset(event.target.value as number); } render() { //let classes = this.props.classes; let presets = this.state.presets; let classes = this.props.classes; return (
{ this.handleSave(); }} size="large">
{true ? ( ) : ( { this.showPresetDialog(true); }} >
{this.state.presets.getSelectedText()}
)}
this.handlePresetMenuClick(e)} size="large"> this.handlePresetsMenuClose()} TransitionComponent={Fade} > this.handlePresetsMenuSave(e)}>Save preset this.handlePresetsMenuSaveAs(e)}>Save preset as... this.handlePresetsMenuRename(e)}>Rename... this.handlePresetsMenuNew(e)}>New... { this.handleDownloadPreset(e); }} >Download preset { this.handleUploadPreset(e) }}>Upload preset this.handleMenuEditPresets()}>Manage presets...
this.handleDialogClose()} /> this.handleRenameDialogClose()} onOk={(name: string) => this.handleRenameDialogOk(name)} /> { this.model.loadPreset(instanceId); }} open={this.state.openUploadPresetDialog} uploadAfter={-1} onClose={() => { this.setState({ openUploadPresetDialog: false }) }} />
); } }); export default PresetSelector;