material-ui -> mui-material migration.

This commit is contained in:
Robin Davies
2022-02-15 15:59:58 -05:00
parent dd4d883b0b
commit ac51296782
19 changed files with 969 additions and 1423 deletions
+2 -2
View File
@@ -34,7 +34,6 @@ add_custom_command(
src/WifiChannel.tsx
src/PluginControlView.tsx
src/TemporaryDrawer.tsx
src/LoadPluginDialogBackup.tsx
src/logo.svg
src/AlsaDeviceInfo.tsx
src/JackServerSettingsDialog.tsx
@@ -42,6 +41,7 @@ add_custom_command(
src/PedalBoardView.tsx
src/MainPage.tsx
src/App.tsx
src/AppThemed.tsx
src/PresetDialog.tsx
src/PluginPreset.tsx
src/react-app-env.d.ts
@@ -89,7 +89,7 @@ add_custom_command(
src/DialogEx.tsx
src/ToobWaveShapeView.tsx
src/FullScreenIME.tsx
src/App.css
src/AppThemed.css
src/PluginPresetSelector.tsx
src/Utility.tsx
src/SelectMidiChannelsDialog.tsx
+12 -12
View File
@@ -1,19 +1,20 @@
import React, { SyntheticEvent, Component } from 'react';
import IconButton from '@material-ui/core/IconButton';
import Typography from '@material-ui/core/Typography';
import IconButton from '@mui/material/IconButton';
import Typography from '@mui/material/Typography';
import { PiPedalModel, PiPedalModelFactory, State } from './PiPedalModel';
import { TransitionProps } from '@material-ui/core/transitions/transition';
import Slide from '@material-ui/core/Slide';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import { Theme, withStyles, WithStyles, createStyles } from '@material-ui/core/styles';
import ArrowBackIcon from '@material-ui/icons/ArrowBack';
import Divider from '@material-ui/core/Divider';
import AppBar from '@mui/material/AppBar';
import Toolbar from '@mui/material/Toolbar';
import ArrowBackIcon from '@mui/icons-material//ArrowBack';
import Divider from '@mui/material/Divider';
import JackHostStatus from './JackHostStatus';
import {PiPedalError} from './PiPedalError';
import DialogEx from './DialogEx';
import { Theme, createStyles } from '@mui/material/styles';
import { withStyles, WithStyles} from '@mui/styles';
import Slide, {SlideProps} from '@mui/material/Slide';
interface AboutDialogProps extends WithStyles<typeof styles> {
open: boolean;
@@ -81,10 +82,9 @@ const styles = (theme: Theme) => createStyles({
const Transition = React.forwardRef(function Transition(
props: TransitionProps & { children?: React.ReactElement },
ref: React.Ref<unknown>,
props: SlideProps, ref: React.Ref<unknown>
) {
return <Slide direction="up" ref={ref} {...props} />;
return (<Slide direction="up" ref={ref} {...props} />);
});
+8 -828
View File
@@ -17,48 +17,10 @@
// 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 } from 'react';
import { ThemeProvider, WithStyles } from '@mui/styles';
import { createTheme, StyledEngineProvider, adaptV4Theme, Theme } from '@mui/material/styles';
import React from 'react';
import { ThemeProvider, createTheme, StyledEngineProvider, Theme } from '@mui/material/styles';
import './App.css';
import AppBar from '@mui/material/AppBar';
import Toolbar from '@mui/material/Toolbar';
import CssBaseline from '@mui/material/CssBaseline';
import Typography from '@mui/material/Typography';
import createStyles from '@mui/styles/createStyles';
import withStyles from '@mui/styles/withStyles';
import IconButton from '@mui/material/IconButton';
import MenuButton from '@mui/icons-material/Menu';
import { TemporaryDrawer } from './TemporaryDrawer';
import FullscreenIcon from '@mui/icons-material/Fullscreen';
import FullscreenExitIcon from '@mui/icons-material/FullscreenExit';
import List from '@mui/material/List';
import Divider from '@mui/material/Divider';
import ListItem from '@mui/material/ListItem';
import ListItemIcon from '@mui/material/ListItemIcon';
import ListItemText from '@mui/material/ListItemText';
import CircularProgress from '@mui/material/CircularProgress';
import { OnChangedHandler } from './ObservableProperty';
import ErrorOutlineIcon from '@mui/icons-material/Error';
import ResizeResponsiveComponent from './ResizeResponsiveComponent';
import Button from '@mui/material/Button';
import PresetSelector from './PresetSelector';
import SettingsDialog from './SettingsDialog';
import AboutDialog from './AboutDialog';
import BankDialog from './BankDialog';
import { PiPedalModelFactory, PiPedalModel, State, ZoomedControlInfo } from './PiPedalModel';
import ZoomedUiControl from './ZoomedUiControl'
import MainPage from './MainPage';
import DialogContent from '@mui/material/DialogContent';
import DialogContentText from '@mui/material/DialogContentText';
import Dialog from '@mui/material/Dialog';
import DialogActions from '@mui/material/DialogActions';
import ListSubheader from '@mui/material/ListSubheader';
import { BankIndex, BankIndexEntry } from './Banks';
import RenameDialog from './RenameDialog';
import JackStatusView from './JackStatusView';
import AppThemed from "./AppThemed";
@@ -71,7 +33,7 @@ declare module '@mui/styles/defaultTheme' {
const theme = createTheme(adaptV4Theme({
const theme = createTheme({
palette: {
primary: {
main: "#324c6c"
@@ -80,809 +42,27 @@ const theme = createTheme(adaptV4Theme({
main: "#FF6060"
}
}
}));
const appStyles = ({ palette, spacing, mixins }: Theme) => createStyles({
loadingContent: {
display: "block",
position: "absolute",
minHeight: "10em",
left: "0px",
top: "0px",
width: "100%",
height: "100%",
background: "#DDD",
opacity: "0.95",
justifyContent: "center",
textAlign: "center",
zIndex: 2010
},
errorContent: {
display: "flex",
flexDirection: "column",
justifyContent: "center",
flexWrap: "nowrap",
alignItems: "center",
position: "fixed",
minHeight: "10em",
left: "0px",
top: "0px",
width: "100%",
height: "100%",
color: "#444",
zIndex: 2000
},
errorContentMask: {
position: "absolute", left: 0, top: 0,
width: "100%", height: "100%",
background: "#BBB",
opacity: 0.95,
zIndex: 1999
},
errorText: {
marginTop: 0,
padding: 0,
marginBottom: 12,
fontWeight: 500,
fontSize: "13pt",
maxWidth: 250,
opacity: 1,
zIndex: 2010,
},
progressText: {
marginTop: 0,
fontWeight: 500,
fontSize: "13pt",
maxWidth: 250,
opacity: 1,
zIndex: 2010,
paddingTop: 12,
},
errorMessageBox: {
flex: "0 0 auto",
width: 300,
marginLeft: "auto",
marginRight: "auto",
zIndex: 2010
},
errorMessage: {
color: '#000',
textAlign: "left",
zIndex: 2010
},
loadingBox: {
position: "relative",
top: "20%",
width: "120px",
color: "#888",
marginLeft: "auto",
marginRight: "auto",
// border: "3px solid #888",
borderRadius: "12px",
padding: "12px",
justifyContent: "center",
textAlign: "center",
opacity: 0.8,
zIndex: 2010
},
loadingBoxItem: {
justifyContent: "center",
textAlign: "center",
zIndex: 2010
},
toolBarContent:
{
position: "absolute", top: 0, width: "100%"
},
toolBarSpacer:
{
position: "relative", flex: "0 0 auto"
},
mainFrame: {
overflow: "hidden",
display: "flex",
flexFlow: "column",
flex: "1 1 100%"
},
toolbarSizingPosition: {
flexGrow: 0,
flexShrink: 1,
width: "100%",
flexBasis: "auto"
},
mainSizingPosition: {
overflow: "hidden",
flex: "1 1 auto"
},
heroContent: {
backgroundColor: palette.background.paper,
position: "relative",
height: "100%",
width: "100%"
},
drawerItem: {
width: 350,
background: "#FF8080"
},
drawerItemFullWidth: {
width: 'auto',
},
icon: {
marginRight: spacing(2),
},
heroButtons: {
marginTop: spacing(4),
},
cardGrid: {
paddingTop: spacing(8),
paddingBottom: spacing(8),
},
card: {
height: '100%',
display: 'flex',
flexDirection: 'column',
},
cardMedia: {
paddingTop: '56.25%', // 16:9
},
cardContent: {
flexGrow: 1,
},
footer: {
backgroundColor: palette.background.paper,
padding: spacing(6),
},
});
function supportsFullScreen(): boolean {
let doc: any = window.document;
let docEl: any = doc.documentElement;
var requestFullScreen = docEl.requestFullscreen || docEl.mozRequestFullScreen || docEl.webkitRequestFullScreen || docEl.msRequestFullscreen;
return (!!requestFullScreen);
}
type AppThemeProps = {
function setFullScreen(value: boolean) {
let doc: any = window.document;
let docEl: any = doc.documentElement;
var requestFullScreen = docEl.requestFullscreen || docEl.mozRequestFullScreen || docEl.webkitRequestFullScreen || docEl.msRequestFullscreen;
var cancelFullScreen = doc.exitFullscreen || doc.mozCancelFullScreen || doc.webkitExitFullscreen || doc.msExitFullscreen;
if (!doc.fullscreenElement && !doc.mozFullScreenElement && !doc.webkitFullscreenElement && !doc.msFullscreenElement) {
requestFullScreen.call(docEl);
}
else {
cancelFullScreen.call(doc);
}
}
function preventDefault(e: SyntheticEvent): void {
e.stopPropagation();
e.preventDefault();
}
type AppState = {
zoomedControlInfo: ZoomedControlInfo | undefined;
isDrawerOpen: boolean;
errorMessage: string;
displayState: State;
canFullScreen: boolean;
isFullScreen: boolean;
tinyToolBar: boolean;
alertDialogOpen: boolean;
alertDialogMessage: string;
isSettingsDialogOpen: boolean;
isDebug: boolean;
renameBankDialogOpen: boolean;
saveBankAsDialogOpen: boolean;
aboutDialogOpen: boolean;
bankDialogOpen: boolean;
editBankDialogOpen: boolean;
zoomedControlOpen: boolean;
presetName: string;
presetChanged: boolean;
banks: BankIndex;
bankDisplayItems: number;
};
interface AppProps extends WithStyles<typeof appStyles> {
}
const App = withStyles(appStyles)(class extends ResizeResponsiveComponent<AppProps, AppState> {
const App = (class extends React.Component {
// Before the component mounts, we initialise our state
model_: PiPedalModel;
errorChangeHandler_: OnChangedHandler<string>;
stateChangeHandler_: OnChangedHandler<State>;
constructor(props: AppProps) {
constructor(props: AppThemeProps) {
super(props);
this.model_ = PiPedalModelFactory.getInstance();
this.model_.zoomedUiControl.addOnChangedHandler(
() => {
this.setState({
zoomedControlOpen: this.model_.zoomedUiControl.get() !== undefined,
zoomedControlInfo: this.model_.zoomedUiControl.get()
});
}
);
this.state = {
zoomedControlInfo: this.model_.zoomedUiControl.get(),
isDrawerOpen: false,
errorMessage: this.model_.errorMessage.get(),
displayState: this.model_.state.get(),
canFullScreen: supportsFullScreen(),
isFullScreen: !!document.fullscreenElement,
tinyToolBar: false,
alertDialogOpen: false,
alertDialogMessage: "",
presetName: this.model_.presets.get().getSelectedText(),
isSettingsDialogOpen: false,
isDebug: true,
presetChanged: this.model_.presets.get().presetChanged,
banks: this.model_.banks.get(),
renameBankDialogOpen: false,
saveBankAsDialogOpen: false,
aboutDialogOpen: false,
bankDialogOpen: false,
editBankDialogOpen: false,
zoomedControlOpen: false,
bankDisplayItems: 5
};
this.errorChangeHandler_ = this.setErrorMessage.bind(this);
this.stateChangeHandler_ = this.setDisplayState.bind(this);
this.presetChangedHandler = this.presetChangedHandler.bind(this);
this.alertMessageChangedHandler = this.alertMessageChangedHandler.bind(this);
this.handleCloseAlert = this.handleCloseAlert.bind(this);
this.banksChangedHandler = this.banksChangedHandler.bind(this);
}
onOpenBank(bankId: number) {
this.model_.openBank(bankId)
.catch((error) => this.model_.showAlert(error));
}
handleSaveBankAsOk(newName: string) {
let currentName = this.model_.banks.get().getSelectedEntryName();
if (currentName === newName) {
this.setState({
renameBankDialogOpen: false,
saveBankAsDialogOpen: false
});
return;
}
if (this.model_.banks.get().nameExists(newName)) {
this.model_.showAlert("A bank by that name already exists.");
return;
}
this.setState({
renameBankDialogOpen: false,
saveBankAsDialogOpen: false
});
this.model_.saveBankAs(this.model_.banks.get().selectedBank, newName)
.catch((error) => {
this.model_.showAlert(error);
});
}
handleBankRenameOk(newName: string) {
let currentName = this.model_.banks.get().getSelectedEntryName();
if (currentName === newName) {
this.setState({
renameBankDialogOpen: false,
saveBankAsDialogOpen: false
});
return;
}
if (this.model_.banks.get().nameExists(newName)) {
this.model_.showAlert("A bank by that name already exists.");
return;
}
this.setState({
renameBankDialogOpen: false
});
this.model_.renameBank(this.model_.banks.get().selectedBank, newName)
.catch((error) => {
this.model_.showAlert(error);
});
}
handleSettingsDialogClose() {
this.setState({
isSettingsDialogOpen: false
});
}
handleDrawerSettingsClick() {
this.setState({
isDrawerOpen: false,
isSettingsDialogOpen: true
});
}
handleDrawerManageBanks() {
this.setState({
isDrawerOpen: false,
bankDialogOpen: true,
editBankDialogOpen: true
});
}
handleDrawerSelectBank() {
this.setState({
isDrawerOpen: false,
bankDialogOpen: true,
editBankDialogOpen: false
});
}
handleDrawerAboutClick() {
this.setState({
aboutDialogOpen: true
});
}
handleDrawerRenameBank() {
this.setState({
isDrawerOpen: false,
renameBankDialogOpen: true,
saveBankAsDialogOpen: false
});
}
handleDrawerSaveBankAs() {
this.setState({
isDrawerOpen: false,
renameBankDialogOpen: false,
saveBankAsDialogOpen: true
});
}
handleCloseAlert(e?: any, reason?: any) {
this.model_.alertMessage.set("");
}
banksChangedHandler() {
this.setState({
banks: this.model_.banks.get()
});
}
presetChangedHandler() {
let presets = this.model_.presets.get();
this.setState({
presetName: presets.getSelectedText(),
presetChanged: presets.presetChanged
});
}
toggleFullScreen(): void {
setFullScreen(this.state.isFullScreen);
this.setState({ isFullScreen: !this.state.isFullScreen });
}
componentDidMount() {
super.componentDidMount();
window.addEventListener("beforeunload", (e) => {
e.preventDefault();
if (this.model_.state.get() === State.Ready) {
e.returnValue = "Are you sure you want to leave this page?";
return "Are you sure you want to leave this page?";
}
});
this.model_.errorMessage.addOnChangedHandler(this.errorChangeHandler_);
this.model_.state.addOnChangedHandler(this.stateChangeHandler_);
this.model_.pedalBoard.addOnChangedHandler(this.presetChangedHandler);
this.model_.alertMessage.addOnChangedHandler(this.alertMessageChangedHandler);
this.model_.banks.addOnChangedHandler(this.banksChangedHandler);
this.alertMessageChangedHandler();
}
updateOverscroll(): void {
if (this.model_.serverVersion) {
// no pull-down refresh on android devices once we're ready (unless we're debug)
let preventOverscroll =
this.model_.state.get() === State.Ready
&& !this.model_.serverVersion.debug;
let overscrollBehavior = preventOverscroll ? "none" : "auto";
document.body.style.overscrollBehavior = overscrollBehavior;
}
}
componentDidUpdate() {
}
componentWillUnmount() {
super.componentWillUnmount();
this.model_.errorMessage.removeOnChangedHandler(this.errorChangeHandler_);
this.model_.state.removeOnChangedHandler(this.stateChangeHandler_);
this.model_.pedalBoard.removeOnChangedHandler(this.presetChangedHandler);
this.model_.banks.addOnChangedHandler(this.banksChangedHandler);
}
alertMessageChangedHandler() {
let message = this.model_.alertMessage.get();
if (message === "") {
this.setState({ alertDialogOpen: false });
// leave the message intact so the dialog can fade.
} else {
this.setState({
alertDialogOpen: true,
alertDialogMessage: message
});
}
}
updateResponsive() {
// functional, but disabled.
// let tinyToolBar_ = this.windowSize.height < 600;
// this.setState({ tinyToolBar: tinyToolBar_ });
let height = this.windowSize.height;
const ENTRY_HEIGHT = 48;
// ENTRY_HEIGHT*6 +K = 727 from observation.
const K = 450;
let bankEntries = Math.floor((height - K) / ENTRY_HEIGHT);
if (bankEntries < 1) bankEntries = 1;
if (bankEntries > 7) bankEntries = 7;
this.setState({ bankDisplayItems: bankEntries });
}
onWindowSizeChanged(width: number, height: number): void {
super.onWindowSizeChanged(width, height);
this.updateResponsive();
}
setErrorMessage(message: string): void {
this.setState({ errorMessage: message });
}
setDisplayState(newState: State): void {
this.updateOverscroll();
this.setState({ displayState: newState });
}
showDrawer() {
this.setState({ isDrawerOpen: true })
}
hideDrawer() {
this.setState({ isDrawerOpen: false })
}
shortBankList(banks: BankIndex): BankIndexEntry[] {
let n = this.state.bankDisplayItems;
let entries = banks.entries;
if (entries.length < n + 1) { // +1 for the .... entry.
return entries;
}
let result: BankIndexEntry[] = [];
let selectedIndex = -1;
for (let i = 0; i < entries.length; ++i) {
if (entries[i].instanceId === banks.selectedBank) {
selectedIndex = i;
break;
}
}
if (n > entries.length) n = entries.length;
if (selectedIndex > n) {
for (let i = 0; i < n - 1; ++i) {
result.push(entries[i]);
}
result.push(entries[selectedIndex]);
} else {
for (let i = 0; i < n; ++i) {
result.push(entries[i]);
}
}
return result;
}
render() {
const { classes } = this.props;
let shortBankList = this.shortBankList(this.state.banks);
let showBankSelectDialog = shortBankList.length !== this.state.banks.entries.length;
return (
<StyledEngineProvider injectFirst>
<ThemeProvider theme={theme}>
<div style={{
minHeight: 345, minWidth: 390,
position: "absolute", width: "100%", height: "100%", background: "#F88", userSelect: "none",
display: "flex", flexDirection: "column", flexWrap: "nowrap",
overscrollBehavior: this.state.isDebug ? "auto" : "none"
}}
onContextMenu={(e) => {
if (!this.model_.serverVersion?.debug ?? false) {
e.preventDefault(); e.stopPropagation();
}
}}
>
<CssBaseline />
{(!this.state.tinyToolBar) ?
(
<AppBar position="absolute" style={{background: "white"}}>
<Toolbar variant="dense" >
<IconButton
edge="start"
aria-label="menu"
onClick={() => { this.showDrawer() }}
size="large">
<MenuButton />
</IconButton>
<div style={{ flex: "1 1 1px" }} />
<div style={{ flex: "0 1 400px", minWidth: 100 }}>
<PresetSelector />
</div>
<div style={{ flex: "2 2 30px" }} />
{this.state.canFullScreen &&
<IconButton
aria-label="menu"
onClick={() => { this.toggleFullScreen(); }}
size="large">
{this.state.isFullScreen ? (
<FullscreenExitIcon />
) : (
<FullscreenIcon />
)}
</IconButton>
}
</Toolbar>
</AppBar>
) : (
<div className={classes.toolBarContent} >
<IconButton
style={{ position: "absolute", left: 12, top: 8, zIndex: 2 }}
aria-label="menu"
onClick={() => { this.showDrawer() }}
size="large">
<MenuButton />
</IconButton>
{this.state.canFullScreen && (
<IconButton
style={{ position: "absolute", right: 8, top: 8, zIndex: 2 }}
aria-label="menu"
onClick={() => { this.toggleFullScreen(); }}
size="large">
{this.state.isFullScreen ? (
<FullscreenExitIcon />
) : (
<FullscreenIcon />
)}
</IconButton>
)}
</div>
)}
<TemporaryDrawer position='left' title="PiPedal"
is_open={this.state.isDrawerOpen} onClose={() => { this.hideDrawer(); }} >
<List subheader={
<ListSubheader component="div" id="nested-list-subheader">Banks</ListSubheader>
}>
{
shortBankList.map((bank) => {
return (
<ListItem button key={'bank' + bank.instanceId} selected={bank.instanceId === this.state.banks.selectedBank}
onClick={() => this.onOpenBank(bank.instanceId)}
>
<ListItemText primary={bank.name} />
</ListItem>
);
})
}
{
showBankSelectDialog && (
<ListItem button key={'bankDOTDOTDOT'} selected={false}
onClick={() => this.handleDrawerSelectBank()}
>
<ListItemText primary={"..."} />
</ListItem>
)
}
</List>
<Divider />
<List>
<ListItem button key='RenameBank' onClick={() => { this.handleDrawerRenameBank() }}>
<ListItemIcon><img src="img/drive_file_rename_outline_black_24dp.svg" alt="" style={{ opacity: 0.6 }} /></ListItemIcon>
<ListItemText primary='Rename Bank' />
</ListItem>
<ListItem button key='SaveBank' onClick={() => { this.handleDrawerSaveBankAs() }} >
<ListItemIcon>
<img src="img/save_bank_as.svg" alt="" style={{ opacity: 0.6 }} />
</ListItemIcon>
<ListItemText primary='Save As New Bank' />
</ListItem>
<ListItem button key='CreateBank' onClick={() => { this.handleDrawerManageBanks(); }}>
<ListItemIcon>
<img src="img/edit_banks.svg" alt="" style={{ opacity: 0.6 }} />
</ListItemIcon>
<ListItemText primary='Manage Banks...' />
</ListItem>
</List>
<Divider />
<List>
<ListItem button key='Settings' onClick={() => { this.handleDrawerSettingsClick() }}>
<ListItemIcon>
<img src="img/settings_black_24dp.svg" alt="" style={{ opacity: 0.6 }} />
</ListItemIcon>
<ListItemText primary='Settings' />
</ListItem>
<ListItem button key='About' onClick={() => { this.handleDrawerAboutClick() }}>
<ListItemIcon>
<img src="img/help_outline_black_24dp.svg" alt="" style={{ opacity: 0.6 }} />
</ListItemIcon>
<ListItemText primary='About' />
</ListItem>
</List>
</TemporaryDrawer>
{!this.state.tinyToolBar && (
<Toolbar className={classes.toolBarSpacer} variant="dense" />
)}
<main className={classes.mainFrame} >
<div className={classes.mainSizingPosition}>
<div className={classes.heroContent}>
{(this.state.displayState !== State.Loading) && (
<MainPage hasTinyToolBar={this.state.tinyToolBar} />
)}
</div>
</div>
</main>
<BankDialog show={this.state.bankDialogOpen} isEditDialog={this.state.editBankDialogOpen} onDialogClose={() => this.setState({ bankDialogOpen: false })} />
<AboutDialog open={this.state.aboutDialogOpen} onClose={() => this.setState({ aboutDialogOpen: false })} />
<SettingsDialog open={this.state.isSettingsDialogOpen} onClose={() => this.handleSettingsDialogClose()} />
<RenameDialog
open={this.state.renameBankDialogOpen || this.state.saveBankAsDialogOpen}
defaultName={this.model_.banks.get().getSelectedEntryName()}
acceptActionName={"Rename"}
onClose={() => {
this.setState({
renameBankDialogOpen: false,
saveBankAsDialogOpen: false
})
}}
onOk={(text: string) => {
if (this.state.renameBankDialogOpen) {
this.handleBankRenameOk(text);
} else if (this.state.saveBankAsDialogOpen) {
this.handleSaveBankAsOk(text);
}
}
}
/>
<ZoomedUiControl
dialogOpen={this.state.zoomedControlOpen}
controlInfo={this.state.zoomedControlInfo}
onDialogClose={() => { this.setState({ zoomedControlOpen: false }); }}
onDialogClosed={() => { this.model_.zoomedUiControl.set(undefined); }
}
/>
<Dialog
open={this.state.alertDialogOpen}
onClose={this.handleCloseAlert}
aria-describedby="alert-dialog-description"
>
<DialogContent>
<DialogContentText id="alert-dialog-description">
{
this.model_.alertMessage.get()
}
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={this.handleCloseAlert} color="primary" autoFocus>
OK
</Button>
</DialogActions>
</Dialog>
<JackStatusView />
<div className={classes.errorContent} style={{ display: this.state.displayState === State.Reconnecting ? "block" : "none" }}
>
<div className={classes.errorContentMask} />
<div className={classes.loadingBox}>
<div className={classes.loadingBoxItem}>
<CircularProgress color="inherit" className={classes.loadingBoxItem} />
</div>
<Typography variant="body2" className={classes.progressText}>
Reconnecting...
</Typography>
</div>
</div>
<div className={classes.errorContent} style={{ display: this.state.displayState === State.Error ? "flex" : "none" }}
onMouseDown={preventDefault} onKeyDown={preventDefault}
>
<div className={classes.errorContentMask} />
<div style={{ flex: "2 2 3px", height: 20 }} >&nbsp;</div>
<div className={classes.errorMessageBox} style={{ position: "relative" }} >
<div style={{ fontSize: "30px", position: "absolute", left: 0, top: 0, color: "#A00" }}>
<ErrorOutlineIcon color="inherit" fontSize="inherit" style={{ float: "left", marginRight: "12px" }} />
</div>
<div style={{ marginLeft: 40, marginTop: 3 }}>
<p className={classes.errorText}>
Error: {this.state.errorMessage}
</p>
</div>
<div style={{ paddingTop: 50, paddingLeft: 36, textAlign: "left" }}>
<Button variant='contained' color="primary" component='button'
onClick={() => window.location.reload()} >
Reload
</Button>
</div>
</div>
<div style={{ flex: "5 5 auto", height: 20 }} >&nbsp;</div>
</div>
<div className={classes.errorContent} style={{ display: this.state.displayState === State.Loading ? "block" : "none" }}>
<div className={classes.errorContentMask} />
<div className={classes.loadingBox}>
<div className={classes.loadingBoxItem}>
<CircularProgress color="inherit" className={classes.loadingBoxItem} />
</div>
<Typography variant="body2" className={classes.loadingBoxItem}>
Loading...
</Typography>
</div>
</div>
</div >
<AppThemed/>
</ThemeProvider>
</StyledEngineProvider>
);
+843
View File
@@ -0,0 +1,843 @@
// Copyright (c) 2021 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 } from 'react';
import { WithStyles } from '@mui/styles';
import './AppThemed.css';
import AppBar from '@mui/material/AppBar';
import Toolbar from '@mui/material/Toolbar';
import CssBaseline from '@mui/material/CssBaseline';
import Typography from '@mui/material/Typography';
import createStyles from '@mui/styles/createStyles';
import withStyles from '@mui/styles/withStyles';
import IconButton from '@mui/material/IconButton';
import MenuButton from '@mui/icons-material/Menu';
import { TemporaryDrawer } from './TemporaryDrawer';
import FullscreenIcon from '@mui/icons-material/Fullscreen';
import FullscreenExitIcon from '@mui/icons-material/FullscreenExit';
import List from '@mui/material/List';
import Divider from '@mui/material/Divider';
import ListItem from '@mui/material/ListItem';
import ListItemIcon from '@mui/material/ListItemIcon';
import ListItemText from '@mui/material/ListItemText';
import CircularProgress from '@mui/material/CircularProgress';
import { OnChangedHandler } from './ObservableProperty';
import ErrorOutlineIcon from '@mui/icons-material/Error';
import ResizeResponsiveComponent from './ResizeResponsiveComponent';
import Button from '@mui/material/Button';
import PresetSelector from './PresetSelector';
import SettingsDialog from './SettingsDialog';
import AboutDialog from './AboutDialog';
import BankDialog from './BankDialog';
import { PiPedalModelFactory, PiPedalModel, State, ZoomedControlInfo } from './PiPedalModel';
import ZoomedUiControl from './ZoomedUiControl'
import MainPage from './MainPage';
import DialogContent from '@mui/material/DialogContent';
import DialogContentText from '@mui/material/DialogContentText';
import Dialog from '@mui/material/Dialog';
import DialogActions from '@mui/material/DialogActions';
import ListSubheader from '@mui/material/ListSubheader';
import { BankIndex, BankIndexEntry } from './Banks';
import RenameDialog from './RenameDialog';
import JackStatusView from './JackStatusView';
import { Theme } from '@mui/material/styles';
const appStyles = (theme: Theme) => createStyles({
loadingContent: {
display: "block",
position: "absolute",
minHeight: "10em",
left: "0px",
top: "0px",
width: "100%",
height: "100%",
background: "#DDD",
opacity: "0.95",
justifyContent: "center",
textAlign: "center",
zIndex: 2010
},
errorContent: {
display: "flex",
flexDirection: "column",
justifyContent: "center",
flexWrap: "nowrap",
alignItems: "center",
position: "fixed",
minHeight: "10em",
left: "0px",
top: "0px",
width: "100%",
height: "100%",
color: "#444",
zIndex: 2000
},
errorContentMask: {
position: "absolute", left: 0, top: 0,
width: "100%", height: "100%",
background: "#BBB",
opacity: 0.95,
zIndex: 1999
},
errorText: {
marginTop: 0,
padding: 0,
marginBottom: 12,
fontWeight: 500,
fontSize: "13pt",
maxWidth: 250,
opacity: 1,
zIndex: 2010,
},
progressText: {
marginTop: 0,
fontWeight: 500,
fontSize: "13pt",
maxWidth: 250,
opacity: 1,
zIndex: 2010,
paddingTop: 12,
},
errorMessageBox: {
flex: "0 0 auto",
width: 300,
marginLeft: "auto",
marginRight: "auto",
zIndex: 2010
},
errorMessage: {
color: '#000',
textAlign: "left",
zIndex: 2010
},
loadingBox: {
position: "relative",
top: "20%",
width: "120px",
color: "#888",
marginLeft: "auto",
marginRight: "auto",
// border: "3px solid #888",
borderRadius: "12px",
padding: "12px",
justifyContent: "center",
textAlign: "center",
opacity: 0.8,
zIndex: 2010
},
loadingBoxItem: {
justifyContent: "center",
textAlign: "center",
zIndex: 2010
},
toolBarContent:
{
position: "absolute", top: 0, width: "100%"
},
toolBarSpacer:
{
position: "relative", flex: "0 0 auto"
},
mainFrame: {
overflow: "hidden",
display: "flex",
flexFlow: "column",
flex: "1 1 100%"
},
toolbarSizingPosition: {
flexGrow: 0,
flexShrink: 1,
width: "100%",
flexBasis: "auto"
},
mainSizingPosition: {
overflow: "hidden",
flex: "1 1 auto"
},
heroContent: {
backgroundColor: "#FFFFFF",
position: "relative",
height: "100%",
width: "100%"
},
drawerItem: {
width: 350,
background: "#FF8080"
},
drawerItemFullWidth: {
width: 'auto',
},
});
function supportsFullScreen(): boolean {
let doc: any = window.document;
let docEl: any = doc.documentElement;
var requestFullScreen = docEl.requestFullscreen || docEl.mozRequestFullScreen || docEl.webkitRequestFullScreen || docEl.msRequestFullscreen;
return (!!requestFullScreen);
}
function setFullScreen(value: boolean) {
let doc: any = window.document;
let docEl: any = doc.documentElement;
var requestFullScreen = docEl.requestFullscreen || docEl.mozRequestFullScreen || docEl.webkitRequestFullScreen || docEl.msRequestFullscreen;
var cancelFullScreen = doc.exitFullscreen || doc.mozCancelFullScreen || doc.webkitExitFullscreen || doc.msExitFullscreen;
if (!doc.fullscreenElement && !doc.mozFullScreenElement && !doc.webkitFullscreenElement && !doc.msFullscreenElement) {
requestFullScreen.call(docEl);
}
else {
cancelFullScreen.call(doc);
}
}
function preventDefault(e: SyntheticEvent): void {
e.stopPropagation();
e.preventDefault();
}
type AppState = {
zoomedControlInfo: ZoomedControlInfo | undefined;
isDrawerOpen: boolean;
errorMessage: string;
displayState: State;
canFullScreen: boolean;
isFullScreen: boolean;
tinyToolBar: boolean;
alertDialogOpen: boolean;
alertDialogMessage: string;
isSettingsDialogOpen: boolean;
isDebug: boolean;
renameBankDialogOpen: boolean;
saveBankAsDialogOpen: boolean;
aboutDialogOpen: boolean;
bankDialogOpen: boolean;
editBankDialogOpen: boolean;
zoomedControlOpen: boolean;
presetName: string;
presetChanged: boolean;
banks: BankIndex;
bankDisplayItems: number;
};
interface AppProps extends WithStyles<typeof appStyles> {
}
const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<AppProps, AppState> {
// Before the component mounts, we initialise our state
model_: PiPedalModel;
errorChangeHandler_: OnChangedHandler<string>;
stateChangeHandler_: OnChangedHandler<State>;
constructor(props: AppProps) {
super(props);
this.model_ = PiPedalModelFactory.getInstance();
this.model_.zoomedUiControl.addOnChangedHandler(
() => {
this.setState({
zoomedControlOpen: this.model_.zoomedUiControl.get() !== undefined,
zoomedControlInfo: this.model_.zoomedUiControl.get()
});
}
);
this.state = {
zoomedControlInfo: this.model_.zoomedUiControl.get(),
isDrawerOpen: false,
errorMessage: this.model_.errorMessage.get(),
displayState: this.model_.state.get(),
canFullScreen: supportsFullScreen(),
isFullScreen: !!document.fullscreenElement,
tinyToolBar: false,
alertDialogOpen: false,
alertDialogMessage: "",
presetName: this.model_.presets.get().getSelectedText(),
isSettingsDialogOpen: false,
isDebug: true,
presetChanged: this.model_.presets.get().presetChanged,
banks: this.model_.banks.get(),
renameBankDialogOpen: false,
saveBankAsDialogOpen: false,
aboutDialogOpen: false,
bankDialogOpen: false,
editBankDialogOpen: false,
zoomedControlOpen: false,
bankDisplayItems: 5
};
this.errorChangeHandler_ = this.setErrorMessage.bind(this);
this.stateChangeHandler_ = this.setDisplayState.bind(this);
this.presetChangedHandler = this.presetChangedHandler.bind(this);
this.alertMessageChangedHandler = this.alertMessageChangedHandler.bind(this);
this.handleCloseAlert = this.handleCloseAlert.bind(this);
this.banksChangedHandler = this.banksChangedHandler.bind(this);
}
onOpenBank(bankId: number) {
this.model_.openBank(bankId)
.catch((error) => this.model_.showAlert(error));
}
handleSaveBankAsOk(newName: string) {
let currentName = this.model_.banks.get().getSelectedEntryName();
if (currentName === newName) {
this.setState({
renameBankDialogOpen: false,
saveBankAsDialogOpen: false
});
return;
}
if (this.model_.banks.get().nameExists(newName)) {
this.model_.showAlert("A bank by that name already exists.");
return;
}
this.setState({
renameBankDialogOpen: false,
saveBankAsDialogOpen: false
});
this.model_.saveBankAs(this.model_.banks.get().selectedBank, newName)
.catch((error) => {
this.model_.showAlert(error);
});
}
handleBankRenameOk(newName: string) {
let currentName = this.model_.banks.get().getSelectedEntryName();
if (currentName === newName) {
this.setState({
renameBankDialogOpen: false,
saveBankAsDialogOpen: false
});
return;
}
if (this.model_.banks.get().nameExists(newName)) {
this.model_.showAlert("A bank by that name already exists.");
return;
}
this.setState({
renameBankDialogOpen: false
});
this.model_.renameBank(this.model_.banks.get().selectedBank, newName)
.catch((error) => {
this.model_.showAlert(error);
});
}
handleSettingsDialogClose() {
this.setState({
isSettingsDialogOpen: false
});
}
handleDrawerSettingsClick() {
this.setState({
isDrawerOpen: false,
isSettingsDialogOpen: true
});
}
handleDrawerManageBanks() {
this.setState({
isDrawerOpen: false,
bankDialogOpen: true,
editBankDialogOpen: true
});
}
handleDrawerSelectBank() {
this.setState({
isDrawerOpen: false,
bankDialogOpen: true,
editBankDialogOpen: false
});
}
handleDrawerAboutClick() {
this.setState({
aboutDialogOpen: true
});
}
handleDrawerRenameBank() {
this.setState({
isDrawerOpen: false,
renameBankDialogOpen: true,
saveBankAsDialogOpen: false
});
}
handleDrawerSaveBankAs() {
this.setState({
isDrawerOpen: false,
renameBankDialogOpen: false,
saveBankAsDialogOpen: true
});
}
handleCloseAlert(e?: any, reason?: any) {
this.model_.alertMessage.set("");
}
banksChangedHandler() {
this.setState({
banks: this.model_.banks.get()
});
}
presetChangedHandler() {
let presets = this.model_.presets.get();
this.setState({
presetName: presets.getSelectedText(),
presetChanged: presets.presetChanged
});
}
toggleFullScreen(): void {
setFullScreen(this.state.isFullScreen);
this.setState({ isFullScreen: !this.state.isFullScreen });
}
componentDidMount() {
super.componentDidMount();
window.addEventListener("beforeunload", (e) => {
e.preventDefault();
if (this.model_.state.get() === State.Ready) {
e.returnValue = "Are you sure you want to leave this page?";
return "Are you sure you want to leave this page?";
}
});
this.model_.errorMessage.addOnChangedHandler(this.errorChangeHandler_);
this.model_.state.addOnChangedHandler(this.stateChangeHandler_);
this.model_.pedalBoard.addOnChangedHandler(this.presetChangedHandler);
this.model_.alertMessage.addOnChangedHandler(this.alertMessageChangedHandler);
this.model_.banks.addOnChangedHandler(this.banksChangedHandler);
this.alertMessageChangedHandler();
}
updateOverscroll(): void {
if (this.model_.serverVersion) {
// no pull-down refresh on android devices once we're ready (unless we're debug)
let preventOverscroll =
this.model_.state.get() === State.Ready
&& !this.model_.serverVersion.debug;
let overscrollBehavior = preventOverscroll ? "none" : "auto";
document.body.style.overscrollBehavior = overscrollBehavior;
}
}
componentDidUpdate() {
}
componentWillUnmount() {
super.componentWillUnmount();
this.model_.errorMessage.removeOnChangedHandler(this.errorChangeHandler_);
this.model_.state.removeOnChangedHandler(this.stateChangeHandler_);
this.model_.pedalBoard.removeOnChangedHandler(this.presetChangedHandler);
this.model_.banks.addOnChangedHandler(this.banksChangedHandler);
}
alertMessageChangedHandler() {
let message = this.model_.alertMessage.get();
if (message === "") {
this.setState({ alertDialogOpen: false });
// leave the message intact so the dialog can fade.
} else {
this.setState({
alertDialogOpen: true,
alertDialogMessage: message
});
}
}
updateResponsive() {
// functional, but disabled.
// let tinyToolBar_ = this.windowSize.height < 600;
// this.setState({ tinyToolBar: tinyToolBar_ });
let height = this.windowSize.height;
const ENTRY_HEIGHT = 48;
// ENTRY_HEIGHT*6 +K = 727 from observation.
const K = 450;
let bankEntries = Math.floor((height - K) / ENTRY_HEIGHT);
if (bankEntries < 1) bankEntries = 1;
if (bankEntries > 7) bankEntries = 7;
this.setState({ bankDisplayItems: bankEntries });
}
onWindowSizeChanged(width: number, height: number): void {
super.onWindowSizeChanged(width, height);
this.updateResponsive();
}
setErrorMessage(message: string): void {
this.setState({ errorMessage: message });
}
setDisplayState(newState: State): void {
this.updateOverscroll();
this.setState({ displayState: newState });
}
showDrawer() {
this.setState({ isDrawerOpen: true })
}
hideDrawer() {
this.setState({ isDrawerOpen: false })
}
shortBankList(banks: BankIndex): BankIndexEntry[] {
let n = this.state.bankDisplayItems;
let entries = banks.entries;
if (entries.length < n + 1) { // +1 for the .... entry.
return entries;
}
let result: BankIndexEntry[] = [];
let selectedIndex = -1;
for (let i = 0; i < entries.length; ++i) {
if (entries[i].instanceId === banks.selectedBank) {
selectedIndex = i;
break;
}
}
if (n > entries.length) n = entries.length;
if (selectedIndex > n) {
for (let i = 0; i < n - 1; ++i) {
result.push(entries[i]);
}
result.push(entries[selectedIndex]);
} else {
for (let i = 0; i < n; ++i) {
result.push(entries[i]);
}
}
return result;
}
render() {
const { classes } = this.props;
let shortBankList = this.shortBankList(this.state.banks);
let showBankSelectDialog = shortBankList.length !== this.state.banks.entries.length;
return (
<div style={{
minHeight: 345, minWidth: 390,
position: "absolute", width: "100%", height: "100%", background: "#F88", userSelect: "none",
display: "flex", flexDirection: "column", flexWrap: "nowrap",
overscrollBehavior: this.state.isDebug ? "auto" : "none"
}}
onContextMenu={(e) => {
if (!this.model_.serverVersion?.debug ?? false) {
e.preventDefault(); e.stopPropagation();
}
}}
>
<CssBaseline />
{(!this.state.tinyToolBar) ?
(
<AppBar position="absolute" style={{ background: "white" }}>
<Toolbar variant="dense" >
<IconButton
edge="start"
aria-label="menu"
onClick={() => { this.showDrawer() }}
size="large">
<MenuButton />
</IconButton>
<div style={{ flex: "1 1 1px" }} />
<div style={{ flex: "0 1 400px", minWidth: 100 }}>
<PresetSelector />
</div>
<div style={{ flex: "2 2 30px" }} />
{this.state.canFullScreen &&
<IconButton
aria-label="menu"
onClick={() => { this.toggleFullScreen(); }}
size="large">
{this.state.isFullScreen ? (
<FullscreenExitIcon />
) : (
<FullscreenIcon />
)}
</IconButton>
}
</Toolbar>
</AppBar>
) : (
<div className={classes.toolBarContent} >
<IconButton
style={{ position: "absolute", left: 12, top: 8, zIndex: 2 }}
aria-label="menu"
onClick={() => { this.showDrawer() }}
size="large">
<MenuButton />
</IconButton>
{this.state.canFullScreen && (
<IconButton
style={{ position: "absolute", right: 8, top: 8, zIndex: 2 }}
aria-label="menu"
onClick={() => { this.toggleFullScreen(); }}
size="large">
{this.state.isFullScreen ? (
<FullscreenExitIcon />
) : (
<FullscreenIcon />
)}
</IconButton>
)}
</div>
)}
<TemporaryDrawer position='left' title="PiPedal"
is_open={this.state.isDrawerOpen} onClose={() => { this.hideDrawer(); }} >
<List subheader={
<ListSubheader component="div" id="nested-list-subheader">Banks</ListSubheader>
}>
{
shortBankList.map((bank) => {
return (
<ListItem button key={'bank' + bank.instanceId} selected={bank.instanceId === this.state.banks.selectedBank}
onClick={() => this.onOpenBank(bank.instanceId)}
>
<ListItemText primary={bank.name} />
</ListItem>
);
})
}
{
showBankSelectDialog && (
<ListItem button key={'bankDOTDOTDOT'} selected={false}
onClick={() => this.handleDrawerSelectBank()}
>
<ListItemText primary={"..."} />
</ListItem>
)
}
</List>
<Divider />
<List>
<ListItem button key='RenameBank' onClick={() => { this.handleDrawerRenameBank() }}>
<ListItemIcon><img src="img/drive_file_rename_outline_black_24dp.svg" alt="" style={{ opacity: 0.6 }} /></ListItemIcon>
<ListItemText primary='Rename Bank' />
</ListItem>
<ListItem button key='SaveBank' onClick={() => { this.handleDrawerSaveBankAs() }} >
<ListItemIcon>
<img src="img/save_bank_as.svg" alt="" style={{ opacity: 0.6 }} />
</ListItemIcon>
<ListItemText primary='Save As New Bank' />
</ListItem>
<ListItem button key='CreateBank' onClick={() => { this.handleDrawerManageBanks(); }}>
<ListItemIcon>
<img src="img/edit_banks.svg" alt="" style={{ opacity: 0.6 }} />
</ListItemIcon>
<ListItemText primary='Manage Banks...' />
</ListItem>
</List>
<Divider />
<List>
<ListItem button key='Settings' onClick={() => { this.handleDrawerSettingsClick() }}>
<ListItemIcon>
<img src="img/settings_black_24dp.svg" alt="" style={{ opacity: 0.6 }} />
</ListItemIcon>
<ListItemText primary='Settings' />
</ListItem>
<ListItem button key='About' onClick={() => { this.handleDrawerAboutClick() }}>
<ListItemIcon>
<img src="img/help_outline_black_24dp.svg" alt="" style={{ opacity: 0.6 }} />
</ListItemIcon>
<ListItemText primary='About' />
</ListItem>
</List>
</TemporaryDrawer>
{!this.state.tinyToolBar && (
<Toolbar className={classes.toolBarSpacer} variant="dense" />
)}
<main className={classes.mainFrame} >
<div className={classes.mainSizingPosition}>
<div className={classes.heroContent}>
{(this.state.displayState !== State.Loading) && (
<MainPage hasTinyToolBar={this.state.tinyToolBar} />
)}
</div>
</div>
</main>
<BankDialog show={this.state.bankDialogOpen} isEditDialog={this.state.editBankDialogOpen} onDialogClose={() => this.setState({ bankDialogOpen: false })} />
<AboutDialog open={this.state.aboutDialogOpen} onClose={() => this.setState({ aboutDialogOpen: false })} />
<SettingsDialog open={this.state.isSettingsDialogOpen} onClose={() => this.handleSettingsDialogClose()} />
<RenameDialog
open={this.state.renameBankDialogOpen || this.state.saveBankAsDialogOpen}
defaultName={this.model_.banks.get().getSelectedEntryName()}
acceptActionName={"Rename"}
onClose={() => {
this.setState({
renameBankDialogOpen: false,
saveBankAsDialogOpen: false
})
}}
onOk={(text: string) => {
if (this.state.renameBankDialogOpen) {
this.handleBankRenameOk(text);
} else if (this.state.saveBankAsDialogOpen) {
this.handleSaveBankAsOk(text);
}
}
}
/>
<ZoomedUiControl
dialogOpen={this.state.zoomedControlOpen}
controlInfo={this.state.zoomedControlInfo}
onDialogClose={() => { this.setState({ zoomedControlOpen: false }); }}
onDialogClosed={() => { this.model_.zoomedUiControl.set(undefined); }
}
/>
<Dialog
open={this.state.alertDialogOpen}
onClose={this.handleCloseAlert}
aria-describedby="alert-dialog-description"
>
<DialogContent>
<DialogContentText id="alert-dialog-description">
{
this.model_.alertMessage.get()
}
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={this.handleCloseAlert} color="primary" autoFocus>
OK
</Button>
</DialogActions>
</Dialog>
<JackStatusView />
<div className={classes.errorContent} style={{ display: this.state.displayState === State.Reconnecting ? "block" : "none" }}
>
<div className={classes.errorContentMask} />
<div className={classes.loadingBox}>
<div className={classes.loadingBoxItem}>
<CircularProgress color="inherit" className={classes.loadingBoxItem} />
</div>
<Typography variant="body2" className={classes.progressText}>
Reconnecting...
</Typography>
</div>
</div>
<div className={classes.errorContent} style={{ display: this.state.displayState === State.Error ? "flex" : "none" }}
onMouseDown={preventDefault} onKeyDown={preventDefault}
>
<div className={classes.errorContentMask} />
<div style={{ flex: "2 2 3px", height: 20 }} >&nbsp;</div>
<div className={classes.errorMessageBox} style={{ position: "relative" }} >
<div style={{ fontSize: "30px", position: "absolute", left: 0, top: 0, color: "#A00" }}>
<ErrorOutlineIcon color="inherit" fontSize="inherit" style={{ float: "left", marginRight: "12px" }} />
</div>
<div style={{ marginLeft: 40, marginTop: 3 }}>
<p className={classes.errorText}>
Error: {this.state.errorMessage}
</p>
</div>
<div style={{ paddingTop: 50, paddingLeft: 36, textAlign: "left" }}>
<Button variant='contained' color="primary" component='button'
onClick={() => window.location.reload()} >
Reload
</Button>
</div>
</div>
<div style={{ flex: "5 5 auto", height: 20 }} >&nbsp;</div>
</div>
<div className={classes.errorContent} style={{ display: this.state.displayState === State.Loading ? "block" : "none" }}>
<div className={classes.errorContentMask} />
<div className={classes.loadingBox}>
<div className={classes.loadingBoxItem}>
<CircularProgress color="inherit" className={classes.loadingBoxItem} />
</div>
<Typography variant="body2" className={classes.loadingBoxItem}>
Loading...
</Typography>
</div>
</div>
</div >
);
}
}
);
export default AppThemed;
+22 -31
View File
@@ -18,34 +18,34 @@
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import React, { Component } from 'react';
import IconButton from '@material-ui/core/IconButton';
import Typography from '@material-ui/core/Typography';
import IconButton from '@mui/material/IconButton';
import Typography from '@mui/material/Typography';
import { PiPedalModel, PiPedalModelFactory } from './PiPedalModel';
import { BankIndexEntry, BankIndex } from './Banks';
import Button from "@material-ui/core/Button";
import ButtonBase from "@material-ui/core/ButtonBase";
import { TransitionProps } from '@material-ui/core/transitions/transition';
import Slide from '@material-ui/core/Slide';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import { Theme, withStyles, WithStyles, createStyles } from '@material-ui/core/styles';
import Button from "@mui/material/Button";
import ButtonBase from "@mui/material/ButtonBase";
import Slide, {SlideProps} from '@mui/material/Slide';
import AppBar from '@mui/material/AppBar';
import Toolbar from '@mui/material/Toolbar';
import { Theme, createStyles } from '@mui/material/styles';
import { WithStyles,withStyles } from "@mui/styles";
import DraggableGrid, { ScrollDirection } from './DraggableGrid';
import Fade from '@material-ui/core/Fade';
import Fade from '@mui/material/Fade';
import SelectHoverBackground from './SelectHoverBackground';
import CloseIcon from '@material-ui/icons/Close';
import ArrowBackIcon from '@material-ui/icons/ArrowBack';
import EditIcon from '@material-ui/icons/Edit';
import CloseIcon from '@mui/icons-material/Close';
import ArrowBackIcon from '@mui/icons-material/ArrowBack';
import EditIcon from '@mui/icons-material/Edit';
import RenameDialog from './RenameDialog';
import MoreVertIcon from '@material-ui/icons/MoreVert';
import ListItemIcon from '@material-ui/core/ListItemIcon';
import ListItemText from '@material-ui/core/ListItemText';
import Menu from '@material-ui/core/Menu';
import MenuItem from '@material-ui/core/MenuItem';
import MoreVertIcon from '@mui/icons-material/MoreVert';
import ListItemIcon from '@mui/material/ListItemIcon';
import ListItemText from '@mui/material/ListItemText';
import Menu from '@mui/material/Menu';
import MenuItem from '@mui/material/MenuItem';
import DialogEx from './DialogEx';
import DialogContent from '@material-ui/core/DialogContent';
import DialogActions from '@material-ui/core/DialogActions';
import DialogContent from '@mui/material/DialogContent';
import DialogActions from '@mui/material/DialogActions';
interface BankDialogProps extends WithStyles<typeof styles> {
show: boolean;
@@ -110,18 +110,9 @@ const styles = (theme: Theme) => createStyles({
const Transition = React.forwardRef(function Transition(
props: TransitionProps & { children?: React.ReactElement },
ref: React.Ref<unknown>,
props: SlideProps, ref: React.Ref<unknown>
) {
return <Slide direction="up" ref={ref} {...props} />;
});
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const ActionBarTransition = React.forwardRef(function Transition(
props: TransitionProps & { children?: React.ReactElement },
ref: React.Ref<unknown>,
) {
return <Slide direction="right" ref={ref} {...props} />;
return (<Slide direction="up" ref={ref} {...props} />);
});
+4 -4
View File
@@ -276,7 +276,7 @@ const JackServerSettingsDialog = withStyles(styles)(
<div>
<FormControl className={classes.formControl}>
<InputLabel htmlFor="jsd_device">Device</InputLabel>
<Select onChange={(e) => this.handleDeviceChanged(e)}
<Select variant="standard" onChange={(e) => this.handleDeviceChanged(e)}
value={this.state.jackServerSettings.alsaDevice}
style={{width: 220}}
inputProps={{
@@ -302,7 +302,7 @@ const JackServerSettingsDialog = withStyles(styles)(
</div><div>
<FormControl className={classes.formControl}>
<InputLabel htmlFor="jsd_sampleRate">Sample rate</InputLabel>
<Select
<Select variant="standard"
onChange={(e) => this.handleRateChanged(e)}
value={this.state.jackServerSettings.sampleRate}
inputProps={{
@@ -322,7 +322,7 @@ const JackServerSettingsDialog = withStyles(styles)(
<div style={{ display: "inline", whiteSpace: "nowrap" }}>
<FormControl className={classes.formControl}>
<InputLabel htmlFor="bufferSize">Buffer size</InputLabel>
<Select
<Select variant="standard"
onChange={(e) => this.handleSizeChanged(e)}
value={this.state.jackServerSettings.bufferSize}
inputProps={{
@@ -340,7 +340,7 @@ const JackServerSettingsDialog = withStyles(styles)(
</FormControl>
<FormControl className={classes.formControl}>
<InputLabel htmlFor="numberofBuffers">Buffers</InputLabel>
<Select
<Select variant="standard"
onChange={(e) => this.handleNumberOfBuffersChanged(e)}
value={this.state.jackServerSettings.numberOfBuffers}
inputProps={{
+23 -23
View File
@@ -18,33 +18,34 @@
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import React, { ReactNode, SyntheticEvent, CSSProperties } from 'react';
import { createStyles, withStyles, WithStyles, Theme } from '@material-ui/core/styles';
import { PiPedalModel, PiPedalModelFactory } from './PiPedalModel';
import { UiPlugin, PluginType } from './Lv2Plugin';
import ButtonBase from '@material-ui/core/ButtonBase';
import Button from '@material-ui/core/Button';
import MenuItem from '@material-ui/core/MenuItem';
import Typography from '@material-ui/core/Typography';
import ButtonBase from '@mui/material/ButtonBase';
import Button from '@mui/material/Button';
import MenuItem from '@mui/material/MenuItem';
import Typography from '@mui/material/Typography';
import PluginInfoDialog from './PluginInfoDialog'
import PluginIcon from './PluginIcon'
import Dialog from '@material-ui/core/Dialog';
import DialogActions from '@material-ui/core/DialogActions';
import DialogContent from '@material-ui/core/DialogContent';
import DialogTitle from '@material-ui/core/DialogTitle';
import Dialog from '@mui/material/Dialog';
import DialogActions from '@mui/material/DialogActions';
import DialogContent from '@mui/material/DialogContent';
import DialogTitle from '@mui/material/DialogTitle';
import SelectHoverBackground from './SelectHoverBackground';
import ArrowBackIcon from '@material-ui/icons/ArrowBack';
import IconButton from '@material-ui/core/IconButton';
import Select from '@material-ui/core/Select';
import ArrowBackIcon from '@mui/icons-material/ArrowBack';
import IconButton from '@mui/material/IconButton';
import Select from '@mui/material/Select';
import PluginClass from './PluginClass'
import ClearIcon from '@material-ui/icons/Clear';
import ClearIcon from '@mui/icons-material/Clear';
import ResizeResponsiveComponent from './ResizeResponsiveComponent';
import { TransitionProps } from '@material-ui/core/transitions/transition';
import Slide from '@material-ui/core/Slide';
import SearchControl from './SearchControl';
import SearchFilter from './SearchFilter';
import { FixedSizeGrid } from 'react-window';
import AutoSizer from 'react-virtualized-auto-sizer';
import Slide, {SlideProps} from '@mui/material/Slide';
import { createStyles, Theme } from '@mui/material/styles';
import { WithStyles, withStyles} from '@mui/styles';
export type CloseEventHandler = () => void;
@@ -167,13 +168,12 @@ type PluginGridState = {
minimumItemWidth: number,
}
const Transition = React.forwardRef(function Transition(
props: TransitionProps & { children?: React.ReactElement<any, any> },
ref: React.Ref<unknown>,
) {
return <Slide direction="up" ref={ref} {...props} />;
});
const Transition = React.forwardRef(function Transition(
props: SlideProps, ref: React.Ref<unknown>
) {
return (<Slide direction="up" ref={ref} {...props} />);
});
export const LoadPluginDialog =
withStyles(pluginGridStyles, { withTheme: true })(
@@ -545,12 +545,12 @@ export const LoadPluginDialog =
}}
/>
</div>
<Select
<Select variant="standard"
defaultValue={this.state.filterType}
key={this.state.filterType}
onChange={(e) => { this.onFilterChange(e); }}
style={{ flex: "0 0 160px" }}
variant="standard">
>
{this.createFilterOptions()}
</Select>
<div style={{ flex: "0 0 auto", marginRight: 24, visibility: this.state.filterType === PluginType.Plugin ? "hidden" : "visible" }} >
-462
View File
@@ -1,462 +0,0 @@
// Copyright (c) 2021 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 React, { ReactNode, SyntheticEvent } from 'react';
import Grid from '@material-ui/core/Grid';
import { createStyles, withStyles, WithStyles, Theme } from '@material-ui/core/styles';
import { PiPedalModel, PiPedalModelFactory } from './PiPedalModel';
import { UiPlugin, PluginType } from './Lv2Plugin';
import Paper from '@material-ui/core/Paper';
import ButtonBase from '@material-ui/core/ButtonBase';
import Button from '@material-ui/core/Button';
import MenuItem from '@material-ui/core/MenuItem';
import Typography from '@material-ui/core/Typography';
import PluginInfoDialog from './PluginInfoDialog'
import PluginIcon from './PluginIcon'
import Dialog from '@material-ui/core/Dialog';
import DialogActions from '@material-ui/core/DialogActions';
import DialogContent from '@material-ui/core/DialogContent';
import DialogTitle from '@material-ui/core/DialogTitle';
import SelectHoverBackground from './SelectHoverBackground';
import ArrowBackIcon from '@material-ui/icons/ArrowBack';
import IconButton from '@material-ui/core/IconButton';
import Select from '@material-ui/core/Select';
import PluginClass from './PluginClass'
import ClearIcon from '@material-ui/icons/Clear';
import ResizeResponsiveComponent from './ResizeResponsiveComponent';
import { TransitionProps } from '@material-ui/core/transitions/transition';
import Slide from '@material-ui/core/Slide';
export type CloseEventHandler = () => void;
export type OkEventHandler = (pluginUri: string) => void;
const NARROW_DISPLAY_THRESHOLD = 600;
const FILTER_STORAGE_KEY = "com.twoplay.pipedal.load_dlg.filter";
const Transition = React.forwardRef(function Transition(
props: TransitionProps & { children?: React.ReactElement },
ref: React.Ref<unknown>,
) {
return <Slide direction="up" ref={ref} {...props} />;
});
const pluginGridStyles = (theme: Theme) => createStyles({
frame: {
position: "relative",
width: "100%",
height: "100%"
},
top: {
top: "0px",
right: "0px",
left: "0px",
bottom: "64px",
position: "relative",
flexGrow: 1,
background: "#eee",
overflowX: "hidden",
overflowY: "visible"
},
bottom: {
position: "relative",
bottom: "0px",
height: "64px",
width: "100%",
display: "flex",
flexDirection: "row",
flexWrap: "nowrap",
justifyContent: "space-between",
paddingLeft: "24px",
paddingRight: "48px",
background: theme.palette.background.paper,
},
paper: {
position: "relative",
overflow: "hidden",
height: "56px",
width: "100%",
background: theme.palette.background.paper
},
buttonBase: {
width: "100%",
height: "100%'"
},
content: {
marginTop: "8px",
marginBottom: "8px",
marginLeft: "12px",
marginRight: "12px",
width: "100%",
overflow: "hidden"
},
table: {
borderCollapse: "collapse",
},
icon: {
width: "24px",
height: "24px",
margin: "0px",
opacity: "0.6"
},
label: {
marginLeft: "8px",
},
control: {
padding: theme.spacing(1),
},
tdText: {
padding: "0px"
}
})
;
interface PluginGridProps extends WithStyles<typeof pluginGridStyles> {
onOk: OkEventHandler;
onCancel: CloseEventHandler;
uri?: string;
minimumItemWidth?: number;
theme: Theme;
open: boolean
};
type PluginGridState = {
selected_uri?: string,
hover_uri?: string,
filterType: PluginType,
client_width: number,
client_height: number,
minimumItemWidth: number,
}
export const LoadPluginDialog =
withStyles(pluginGridStyles, { withTheme: true })(
class extends ResizeResponsiveComponent<PluginGridProps, PluginGridState>
{
model: PiPedalModel;
constructor(props: PluginGridProps) {
super(props);
this.model = PiPedalModelFactory.getInstance();
let filterType_ = PluginType.Plugin; // i.e. "Any".
let persistedFilter = window.localStorage.getItem(FILTER_STORAGE_KEY);
if (persistedFilter) {
filterType_ = persistedFilter as PluginType;
}
this.state = {
selected_uri: this.props.uri,
hover_uri: "",
filterType: filterType_,
client_width: window.innerWidth,
client_height: window.innerHeight,
minimumItemWidth: props.minimumItemWidth ? props.minimumItemWidth : 220
};
this.updateWindowSize = this.updateWindowSize.bind(this);
this.handleCancel = this.handleCancel.bind(this);
this.handleOk = this.handleOk.bind(this);
}
updateWindowSize() {
this.setState({
client_width: window.innerWidth,
client_height: window.innerHeight
});
}
componentDidMount() {
super.componentDidMount();
this.updateWindowSize();
window.addEventListener('resize', this.updateWindowSize);
}
componentWillUnmount() {
super.componentWillUnmount();
window.removeEventListener('resize', this.updateWindowSize);
}
onWindowSizeChanged(width: number,height: number): void {
super.onWindowSizeChanged(width,height);
}
onFilterChange(e: any) {
let value = e.target.value as PluginType;
window.localStorage.setItem(FILTER_STORAGE_KEY, value as string);
this.setState({ filterType: value });
}
onClearFilter(): void {
let value = PluginType.Plugin;
window.localStorage.setItem(FILTER_STORAGE_KEY, value as string);
this.setState({ filterType: value });
}
selectItem(item: number): void {
let uri: string = "";
let plugins = this.model.ui_plugins.get();
if (item >= 0 && item < plugins.length) {
uri = plugins[item].uri;
}
if (uri !== this.state.selected_uri) {
this.setState({ selected_uri: uri });
}
};
handleCancel(e: SyntheticEvent): void {
e.preventDefault();
this.cancel();
}
handleOk(e: SyntheticEvent): void {
e.preventDefault();
if (this.state.selected_uri) {
this.props.onOk(this.state.selected_uri);
}
}
onDoubleClick(e: SyntheticEvent, uri: string): void {
this.props.onOk(uri);
}
cancel(): void {
this.props.onCancel();
}
fireSelected(item?: UiPlugin) {
if (item) {
this.setState({ selected_uri: item.uri });
}
}
setHoverUri(uri: string) {
this.setState({ hover_uri: uri });
}
onClick(e: SyntheticEvent, uri: string): void {
this.setState({ selected_uri: uri });
}
handleMouseEnter(e: SyntheticEvent, uri: string): void {
this.setHoverUri(uri);
}
handleMouseLeave(e: SyntheticEvent, uri: string): void {
this.setHoverUri("");
}
onInfoClicked(): void {
// let selectedUri = this.state.selected_uri;
}
stereo_indicator(uiPlugin?: UiPlugin): string {
if (!uiPlugin) return "";
if (uiPlugin.audio_inputs === 2 || uiPlugin.audio_outputs === 2) {
return " (Stereo)";
}
return "";
}
info_string(uiPlugin?: UiPlugin): string {
if (uiPlugin === undefined) return "";
let result = uiPlugin.name;
if (uiPlugin.author_name !== "") {
result += ", " + uiPlugin.author_name;
}
result += this.stereo_indicator(uiPlugin);
return result;
}
createFilterChildren(result: ReactNode[], classNode: PluginClass, level: number): void {
for (let i = 0; i < classNode.children.length; ++i) {
let child = classNode.children[i];
let name = "\u00A0".repeat(level * 3+1) + child.display_name;
result.push((<MenuItem value={child.plugin_type}>{name}</MenuItem>));
if (child.children.length !== 0) {
this.createFilterChildren(result, child, level + 1);
}
}
}
createFilterOptions(): ReactNode[] {
let classes = this.model.plugin_classes.get();
let result: ReactNode[] = [];
result.push((<MenuItem value={PluginType.Plugin}>&nbsp;All</MenuItem>));
this.createFilterChildren(result, classes, 1);
return result;
}
filterPlugins(plugins: UiPlugin[]): ReactNode[] {
let result: ReactNode[] = [];
let filterType = this.state.filterType;
let classes = this.props.classes;
let rootClass = this.model.plugin_classes.get();
for (let i = 0; i < plugins.length; ++i) {
let value = plugins[i];
if (filterType === PluginType.Plugin || rootClass.is_type_of(filterType, value.plugin_type)) {
result.push(
(
<Grid key={value.uri} xs={6} sm={6} md={4} lg={3} xl={3} item
onDoubleClick={(e) => { this.onDoubleClick(e, value.uri) }}
onClick={(e) => { this.onClick(e, value.uri) }}
onMouseEnter={(e) => { this.handleMouseEnter(e, value.uri) }}
onMouseLeave={(e) => { this.handleMouseLeave(e, value.uri) }}
>
<Paper className={classes.paper} >
<ButtonBase className={classes.buttonBase} focusRipple>
<SelectHoverBackground selected={value.uri === this.state.selected_uri} showHover={true} />
<div className={classes.content}>
<div style={{ display: "flex", flexDirection: "row", justifyContent: "flex-start", alignItems: "start", flexWrap: "nowrap" }} >
<div style={{ flex: "0 1 auto" }}>
<PluginIcon pluginType={value.plugin_type} pluginUri={value.uri} size={24} />
</div>
<div style={{ display: "flex", flexDirection: "column", flex: "1 1 auto", width: "100%" }}>
<Typography className={classes.label}
display='block' variant='body2' align="left" color="textPrimary" noWrap
>{value.name}
</Typography>
<Typography className={classes.label}
display='block' variant='caption' align="left" noWrap
>
{value.plugin_display_type} {this.stereo_indicator(value)}
</Typography>
</div>
</div>
</div>
</ButtonBase>
</Paper>
</Grid>
)
);
}
}
return result;
}
render() {
const { classes } = this.props;
let model = this.model;
let plugins = model.ui_plugins.get();
let selectedPlugin: UiPlugin | undefined = undefined;
if (this.state.selected_uri) {
let t = this.model.getUiPlugin(this.state.selected_uri);
if (t) selectedPlugin = t;
}
return (
<React.Fragment>
<Dialog
TransitionComponent={Transition}
fullScreen={true}
maxWidth={false}
open={this.props.open}
scroll="body"
onClose={this.handleCancel}
style={{ overflowX: "hidden", overflowY: "hidden", display: "flex", flexDirection:"column",flexWrap:"nowrap" }}
aria-labelledby="select-plugin-dialog-title">
<DialogTitle id="select-plugin-dialog-title" style={{ flex: "0 0 auto"}}>
<div style={{ display: "flex", flexDirection: "row", flexWrap: "nowrap", width: "100%", alignItems: "center" }}>
<IconButton onClick={() => { this.cancel(); }} style={{ flex: "0 0 auto" }} >
<ArrowBackIcon />
</IconButton>
<Typography display="block" variant="h6" style={{ flex: "0 1 auto" }}>
{ this.state.client_width > 520 ? "Select Plugin" : "" }
</Typography>
<div style={{ flex: "1 1 auto" }} />
<Select
defaultValue={this.state.filterType}
key={this.state.filterType}
onChange={(e) => { this.onFilterChange(e); }}
style={{ flex: "0 0 160px" }}
variant="standard">
{this.createFilterOptions()}
</Select>
<div style={{ flex: "0 0 auto", marginRight: 24, visibility: this.state.filterType === PluginType.Plugin? "hidden": "visible" }} >
<IconButton onClick={() => { this.onClearFilter(); }}>
<ClearIcon fontSize='small' style={{ opacity: 0.6 }} />
</IconButton>
</div>
</div>
</DialogTitle>
<DialogContent dividers style={{ height: this.state.client_height - (this.state.client_width < NARROW_DISPLAY_THRESHOLD ? 288: 220),
background: "#eee", display: "1 1 flex"}} >
<Grid container justify="flex-start" spacing={1} style={{ background: "#EEE" }}>
{
this.filterPlugins(plugins)
}
</Grid>
</DialogContent>
{ (this.state.client_width >= NARROW_DISPLAY_THRESHOLD)? (
<DialogActions style={{flex: "0 0 auto"}} >
<div className={classes.bottom}>
<div style={{ display: "flex", justifyContent: "start", alignItems: "center", flex: "1 1 auto", height: "100%", overflow: "hidden" }} >
<PluginInfoDialog plugin_uri={this.state.selected_uri ?? ""} />
<Typography display='block' variant='body2' color="textPrimary" noWrap >
{this.info_string(selectedPlugin)}
</Typography>
</div>
<div style={{ position: "relative", float: "right", flex: "0 1 200px", width: 200, display: "flex", alignItems: "center" }}>
<Button onClick={this.handleCancel} style={{ width: 120 }} >Cancel</Button>
<Button onClick={this.handleOk} color="secondary" disabled={selectedPlugin === null} style={{ width: 180 }} >SELECT</Button>
</div>
</div>
</DialogActions>
) :(
<DialogActions style={{flex: "0 0 auto", display: "block"}} >
<div style={{ display: "flex", justifyContent: "start", alignItems: "center", flex: "1 1 auto", overflow: "hidden" }} >
<PluginInfoDialog plugin_uri={this.state.selected_uri ?? ""} />
<div style={{width: 1, height: 48}} />
<Typography display='block' variant='body2' color="textPrimary" noWrap >
{this.info_string(selectedPlugin)}
</Typography>
</div>
<div className={classes.bottom}>
<div style={{flex: "1 1 1px"}}/>
<div style={{ position: "relative", flex: "0 1 auto", display: "flex", alignItems: "center" }}>
<Button onClick={this.handleCancel} style={{ width: 120, height: 48 }} >Cancel</Button>
<Button onClick={this.handleOk} color="secondary" disabled={selectedPlugin === null} style={{ width: 120, height: 48 }} >SELECT</Button>
</div>
</div>
</DialogActions>
)}
</Dialog>
</React.Fragment >
);
}
}
);
export default LoadPluginDialog;
+1 -1
View File
@@ -385,7 +385,7 @@ export const MainPage =
}} >
<div style={{ flex: "0 0 auto", width: 80 }} >
<div style={{ display: bypassVisible ? "block" : "none", width: 80 }} >
<Switch checked={bypassChecked} onChange={this.handleEnableCurrentItemChanged} />
<Switch color="secondary" checked={bypassChecked} onChange={this.handleEnableCurrentItemChanged} />
</div>
</div>
{
+5 -5
View File
@@ -168,7 +168,7 @@ const MidiBindingView =
return (
<div style={{ display: "flex", flexDirection: "row", flexWrap: "wrap", justifyContent: "left", alignItems: "center", minHeight: 48 }}>
<div className={classes.controlDiv} >
<Select
<Select variant="standard"
style={{ width: 80, }}
onChange={(e, extra) => this.handleTypeChange(e, extra)}
value={midiBinding.bindingType}
@@ -184,7 +184,7 @@ const MidiBindingView =
(midiBinding.bindingType === MidiBinding.BINDING_TYPE_NOTE) &&
(
<div className={classes.controlDiv2} >
<Select
<Select variant="standard"
style={{ width:80}}
onChange={(e, extra) => this.handleNoteChange(e, extra)}
value={midiBinding.note}
@@ -218,7 +218,7 @@ const MidiBindingView =
(
<div className={classes.controlDiv2} >
<Select
<Select variant="standard"
style={{ width: 80 }}
onChange={(e, extra) => this.handleControlChange(e, extra)}
value={midiBinding.control}
@@ -252,7 +252,7 @@ const MidiBindingView =
((canLatch) &&
(
<div className={classes.controlDiv} >
<Select
<Select variant="standard"
style={{ width: 120 }}
onChange={(e, extra) => this.handleLatchControlTypeChange(e, extra)}
value={midiBinding.switchControlType}
@@ -276,7 +276,7 @@ const MidiBindingView =
(showLinearControlTypeSelect) &&
(
<div className={classes.controlDiv} >
<Select
<Select variant="standard"
style={{ width: 120 }}
onChange={(e, extra) => this.handleLinearControlTypeChange(e, extra)}
value={midiBinding.linearControlType}
+3 -3
View File
@@ -525,7 +525,7 @@ const PluginControl =
if (control.isOnOffSwitch()) {
// normal gray unchecked state.
return (
<Switch checked={value !== 0}
<Switch checked={value !== 0} color="secondary"
onChange={(event) => {
this.onCheckChanged(event.target.checked);
}}
@@ -535,7 +535,7 @@ const PluginControl =
if (control.isAbToggle()) {
// unchecked color is not gray.
return (
<Switch checked={value !== 0}
<Switch checked={value !== 0} color="secondary"
onChange={(event) => {
this.onCheckChanged(event.target.checked);
}}
@@ -547,7 +547,7 @@ const PluginControl =
);
} else {
return (
<Select
<Select variant="standard"
ref={this.selectRef}
value={control.clampSelectValue(value)}
onChange={this.onSelectChanged}
-1
View File
@@ -368,7 +368,6 @@ const PluginControlView =
for (let i = 0; i < controls.length; ++i)
{
controls[i].key = 'k'+i;
result.push(controls[i]);
}
+23 -29
View File
@@ -18,32 +18,35 @@
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import React, { SyntheticEvent,Component } from 'react';
import IconButton from '@material-ui/core/IconButton';
import Typography from '@material-ui/core/Typography';
import IconButton from '@mui/material/IconButton';
import Typography from '@mui/material/Typography';
import { PiPedalModel, PiPedalModelFactory, PresetIndexEntry, PresetIndex } from './PiPedalModel';
import Button from "@material-ui/core/Button";
import ButtonBase from "@material-ui/core/ButtonBase";
import { TransitionProps } from '@material-ui/core/transitions/transition';
import Slide from '@material-ui/core/Slide' ;
import Button from "@mui/material/Button";
import ButtonBase from "@mui/material/ButtonBase";
import DialogEx from './DialogEx';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import { Theme, withStyles, WithStyles, createStyles } from '@material-ui/core/styles';
import AppBar from '@mui/material/AppBar';
import Toolbar from '@mui/material/Toolbar';
import DraggableGrid, { ScrollDirection } from './DraggableGrid';
import MoreVertIcon from '@material-ui/icons/MoreVert';
import ListItemIcon from '@material-ui/core/ListItemIcon';
import ListItemText from '@material-ui/core/ListItemText';
import Menu from '@material-ui/core/Menu';
import MenuItem from '@material-ui/core/MenuItem';
import Fade from '@material-ui/core/Fade';
import MoreVertIcon from '@mui/icons-material//MoreVert';
import ListItemIcon from '@mui/material/ListItemIcon';
import ListItemText from '@mui/material/ListItemText';
import Menu from '@mui/material/Menu';
import MenuItem from '@mui/material/MenuItem';
import Fade from '@mui/material/Fade';
import UploadDialog from './UploadDialog';
import SelectHoverBackground from './SelectHoverBackground';
import CloseIcon from '@material-ui/icons/Close';
import ArrowBackIcon from '@material-ui/icons/ArrowBack';
import EditIcon from '@material-ui/icons/Edit';
import CloseIcon from '@mui/icons-material//Close';
import ArrowBackIcon from '@mui/icons-material//ArrowBack';
import EditIcon from '@mui/icons-material//Edit';
import RenameDialog from './RenameDialog';
import Slide, {SlideProps} from '@mui/material/Slide';
import { createStyles, Theme } from '@mui/material/styles';
import { WithStyles, withStyles} from '@mui/styles';
interface PresetDialogProps extends WithStyles<typeof styles> {
show: boolean;
isEditDialog: boolean;
@@ -108,18 +111,9 @@ const styles = (theme: Theme) => createStyles({
const Transition = React.forwardRef(function Transition(
props: TransitionProps & { children?: React.ReactElement },
ref: React.Ref<unknown>,
props: SlideProps, ref: React.Ref<unknown>
) {
return <Slide direction="up" ref={ref} {...props} />;
});
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const ActionBarTransition = React.forwardRef(function Transition(
props: TransitionProps & { children?: React.ReactElement },
ref: React.Ref<unknown>,
) {
return <Slide direction="right" ref={ref} {...props} />;
return (<Slide direction="up" ref={ref} {...props} />);
});
+1 -1
View File
@@ -286,7 +286,7 @@ const PresetSelector =
justifyContent: "left", flexWrap: "nowrap", alignItems: "center", height: "100%", position: "relative" }}>
<div style={{ flex: "1 1 auto", minWidth: 60, maxWidth: 300, position: "relative", paddingRight: 12 }} >
{true ? (
<Select
<Select variant="standard"
className={classes.select}
style={{ width: "100%", position: "relative", top: 0}} disabled={!this.state.enabled}
onChange={(e, extra) => this.handleChange(e, extra)}
+14 -13
View File
@@ -18,18 +18,15 @@
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import React, { SyntheticEvent, Component } from 'react';
import IconButton from '@material-ui/core/IconButton';
import Typography from '@material-ui/core/Typography';
import IconButton from '@mui/material/IconButton';
import Typography from '@mui/material/Typography';
import { PiPedalModel, PiPedalModelFactory, State } from './PiPedalModel';
import ButtonBase from "@material-ui/core/ButtonBase";
import { TransitionProps } from '@material-ui/core/transitions/transition';
import Slide from '@material-ui/core/Slide';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import { Theme, withStyles, WithStyles, createStyles } from '@material-ui/core/styles';
import ArrowBackIcon from '@material-ui/icons/ArrowBack';
import ButtonBase from "@mui/material/ButtonBase";
import AppBar from '@mui/material/AppBar';
import Toolbar from '@mui/material/Toolbar';
import ArrowBackIcon from '@mui/icons-material//ArrowBack';
import JackConfiguration, { JackChannelSelection } from './Jack';
import Divider from '@material-ui/core/Divider';
import Divider from '@mui/material/Divider';
import SelectChannelsDialog from './SelectChannelsDialog';
import SelectMidiChannelsDialog from './SelectMidiChannelsDialog';
import SelectHoverBackground from './SelectHoverBackground';
@@ -40,6 +37,10 @@ import WifiConfigSettings from './WifiConfigSettings';
import WifiConfigDialog from './WifiConfigDialog';
import DialogEx from './DialogEx'
import Slide, {SlideProps} from '@mui/material/Slide';
import { createStyles, Theme } from '@mui/material/styles';
import { WithStyles, withStyles} from '@mui/styles';
interface SettingsDialogProps extends WithStyles<typeof styles> {
@@ -119,13 +120,13 @@ const styles = (theme: Theme) => createStyles({
const Transition = React.forwardRef(function Transition(
props: TransitionProps & { children?: React.ReactElement },
ref: React.Ref<unknown>,
props: SlideProps, ref: React.Ref<unknown>
) {
return <Slide direction="up" ref={ref} {...props} />;
return (<Slide direction="up" ref={ref} {...props} />);
});
const SettingsDialog = withStyles(styles, { withTheme: true })(
class extends Component<SettingsDialogProps, SettingsDialogState> {
+4 -3
View File
@@ -29,7 +29,8 @@ import ArrowBackIcon from '@mui/icons-material/ArrowBack';
import { Theme } from '@mui/material/styles';
const drawerStyles = ({ palette }: Theme) => createStyles({
const drawerStyles = (theme: Theme) => {
return createStyles({
list: {
width: 250,
},
@@ -39,10 +40,10 @@ const drawerStyles = ({ palette }: Theme) => createStyles({
drawer_header: {
color: 'white',
background: palette.primary.main,
background: theme.palette.primary.main,
}
});
})};
type Anchor = 'top' | 'left' | 'bottom' | 'right';
+3 -3
View File
@@ -263,7 +263,7 @@ const WifiConfigDialog = withStyles(styles, { withTheme: true })(
<FormControlLabel
control={(
<Switch
<Switch
checked={this.state.enabled}
onChange={(e: any) => this.handleEnableChanged(e)}
color="secondary"
@@ -302,7 +302,7 @@ const WifiConfigDialog = withStyles(styles, { withTheme: true })(
<div style={{ marginBottom: 16}}>
<FormControl>
<InputLabel htmlFor="countryCodeSelect">Country</InputLabel>
<Select id="countryCodeSelect" value={this.state.countryCode} style={{width: 220}}
<Select variant="standard" id="countryCodeSelect" value={this.state.countryCode} style={{width: 220}}
onChange={(event)=>this.handleCountryChanged(event)} >
{Object.entries(this.model.countryCodes).map(([key,value])=> {
return (
@@ -316,7 +316,7 @@ const WifiConfigDialog = withStyles(styles, { withTheme: true })(
<div style={{ marginBottom: 24}}>
<FormControl>
<InputLabel htmlFor="channelSelect">Channel</InputLabel>
<Select id="channelSelect" value={this.state.channel} style={{width: 220}} onChange={(e)=>{
<Select variant="standard" id="channelSelect" value={this.state.channel} style={{width: 220}} onChange={(e)=>{
this.handleChannelChange(e);
}}>
{this.state.wifiChannels.map((channel)=> {
+1 -2
View File
@@ -19,8 +19,7 @@
import React, {SyntheticEvent} from 'react';
import { Theme } from '@mui/material/styles';
import { WithStyles } from '@mui/styles';
import withStyles from '@mui/styles/withStyles';
import { WithStyles,withStyles } from '@mui/styles';
import createStyles from '@mui/styles/createStyles';
import { ZoomedControlInfo } from './PiPedalModel';
import DialogEx from './DialogEx';