Screen orientation, Keep Display on (in Android Client)
This commit is contained in:
Binary file not shown.
@@ -36,6 +36,7 @@ header_pages:
|
|||||||
theme: minima
|
theme: minima
|
||||||
plugins:
|
plugins:
|
||||||
- jekyll-feed
|
- jekyll-feed
|
||||||
|
- jekyll-seo-tag
|
||||||
|
|
||||||
include:
|
include:
|
||||||
- .well-known
|
- .well-known
|
||||||
|
|||||||
@@ -313,6 +313,7 @@ int main(int argc, char *argv[])
|
|||||||
sigset_t sigSet;
|
sigset_t sigSet;
|
||||||
int s;
|
int s;
|
||||||
sigemptyset(&sigSet);
|
sigemptyset(&sigSet);
|
||||||
|
|
||||||
sigaddset(&sigSet, SIGINT);
|
sigaddset(&sigSet, SIGINT);
|
||||||
sigaddset(&sigSet, SIGTERM);
|
sigaddset(&sigSet, SIGTERM);
|
||||||
sigaddset(&sigSet, SIGUSR1);
|
sigaddset(&sigSet, SIGUSR1);
|
||||||
|
|||||||
+16
-16
@@ -101,22 +101,22 @@
|
|||||||
// Run the function when the window loads
|
// Run the function when the window loads
|
||||||
window.addEventListener('load', removeHashOnLoad);
|
window.addEventListener('load', removeHashOnLoad);
|
||||||
|
|
||||||
|
// used by Android client to perform focus scrolling on keyboard open.
|
||||||
function getFocusedElementBounds() {
|
// function getFocusedElementBounds() {
|
||||||
let focusedElement = document.activeElement;
|
// let focusedElement = document.activeElement;
|
||||||
if (focusedElement && focusedElement !== document.body) {
|
// if (focusedElement && focusedElement !== document.body) {
|
||||||
let rect = focusedElement.getBoundingClientRect();
|
// let rect = focusedElement.getBoundingClientRect();
|
||||||
return {
|
// return {
|
||||||
top: rect.top,
|
// top: rect.top,
|
||||||
left: rect.left,
|
// left: rect.left,
|
||||||
right: rect.right,
|
// right: rect.right,
|
||||||
bottom: rect.bottom,
|
// bottom: rect.bottom,
|
||||||
windowWidth: window.innerWidth,
|
// windowWidth: window.innerWidth,
|
||||||
windowHeight: window.innerHeight,
|
// windowHeight: window.innerHeight,
|
||||||
};
|
// };
|
||||||
}
|
// }
|
||||||
return null;
|
// return null;
|
||||||
}
|
// }
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,11 @@ export interface AndroidHostInterface {
|
|||||||
setThemePreference(theme: number): void;
|
setThemePreference(theme: number): void;
|
||||||
getThemePreference(): number;
|
getThemePreference(): number;
|
||||||
isDarkTheme?: ()=> boolean;
|
isDarkTheme?: ()=> boolean;
|
||||||
|
setServerVersion(serverVersion: string) : void;
|
||||||
|
setKeepScreenOn(keepScreenOn: boolean): void;
|
||||||
|
getKeepScreenOn(): boolean;
|
||||||
|
setScreenOrientation(orientation: number): void;
|
||||||
|
getScreenOrientation(): number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export class FakeAndroidHost implements AndroidHostInterface
|
export class FakeAndroidHost implements AndroidHostInterface
|
||||||
@@ -40,7 +45,7 @@ export class FakeAndroidHost implements AndroidHostInterface
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
getHostVersion(): string {
|
getHostVersion(): string {
|
||||||
return "Fake Android 1.0";
|
return "Fake Host: v1.1.26";
|
||||||
}
|
}
|
||||||
chooseNewDevice(): void {
|
chooseNewDevice(): void {
|
||||||
|
|
||||||
@@ -64,6 +69,21 @@ export class FakeAndroidHost implements AndroidHostInterface
|
|||||||
getThemePreference(): number {
|
getThemePreference(): number {
|
||||||
return this.theme;
|
return this.theme;
|
||||||
}
|
}
|
||||||
|
setServerVersion(_serverVersion: string): void {
|
||||||
|
// No-op for fake host
|
||||||
|
}
|
||||||
|
|
||||||
|
private keepScreenOn = false;
|
||||||
|
setKeepScreenOn(keepScreenOn: boolean): void {this.keepScreenOn = keepScreenOn; };
|
||||||
|
getKeepScreenOn(): boolean { return this.keepScreenOn; };
|
||||||
|
|
||||||
|
private screenOrientation = 0;
|
||||||
|
setScreenOrientation(_orientation: number): void {
|
||||||
|
this.screenOrientation = _orientation;
|
||||||
|
}
|
||||||
|
getScreenOrientation(): number {
|
||||||
|
return this.screenOrientation;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
export function isAndroidHosted(): boolean {
|
export function isAndroidHosted(): boolean {
|
||||||
return ((window as any).AndroidHost as AndroidHostInterface) !== undefined;
|
return ((window as any).AndroidHost as AndroidHostInterface) !== undefined;
|
||||||
|
|||||||
@@ -1000,7 +1000,7 @@ export
|
|||||||
<ListItemIcon >
|
<ListItemIcon >
|
||||||
<VolunteerActivismIcon className={classes.menuIcon} color="inherit" />
|
<VolunteerActivismIcon className={classes.menuIcon} color="inherit" />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText primary='Donations' />
|
<ListItemText primary='Sponsorship' />
|
||||||
</ListItemButton>
|
</ListItemButton>
|
||||||
</List>
|
</List>
|
||||||
|
|
||||||
|
|||||||
@@ -23,8 +23,9 @@ import { createStyles } from './WithStyles';
|
|||||||
|
|
||||||
// import Tone3000Dialog from './Tone3000Dialog';
|
// import Tone3000Dialog from './Tone3000Dialog';
|
||||||
import Tone3000HelpDialog from './Tone3000HelpDialog';
|
import Tone3000HelpDialog from './Tone3000HelpDialog';
|
||||||
|
import GuitarMLHelpDialog from './GuitarMlHelpDialog';
|
||||||
import HelpOutlineIcon from '@mui/icons-material/HelpOutline';
|
import HelpOutlineIcon from '@mui/icons-material/HelpOutline';
|
||||||
import Link from '@mui/material/Link';
|
import LinkEx from './LinkEx';
|
||||||
import DraggableButtonBase from './DraggableButtonBase';
|
import DraggableButtonBase from './DraggableButtonBase';
|
||||||
import CloseIcon from '@mui/icons-material/Close';
|
import CloseIcon from '@mui/icons-material/Close';
|
||||||
import { Theme } from '@mui/material/styles';
|
import { Theme } from '@mui/material/styles';
|
||||||
@@ -69,6 +70,7 @@ import { getAlbumArtUri, getTrackTitle } from './AudioFileMetadata';
|
|||||||
|
|
||||||
|
|
||||||
const ToobNamModelFileUrl = "http://two-play.com/plugins/toob-nam#modelFile";
|
const ToobNamModelFileUrl = "http://two-play.com/plugins/toob-nam#modelFile";
|
||||||
|
const ToobMlModelFileUrl = "http://two-play.com/plugins/toob-ml#modelFile";
|
||||||
|
|
||||||
const AUTOSCROLL_TICK_DELAY = 30;
|
const AUTOSCROLL_TICK_DELAY = 30;
|
||||||
const AUTOSCROLL_THRESHOLD = 48;
|
const AUTOSCROLL_THRESHOLD = 48;
|
||||||
@@ -168,7 +170,8 @@ export interface FilePropertyDialogState {
|
|||||||
multiSelect: boolean,
|
multiSelect: boolean,
|
||||||
selectedFiles: string[],
|
selectedFiles: string[],
|
||||||
//openTone3000Dialog: boolean,
|
//openTone3000Dialog: boolean,
|
||||||
openTone3000Help: boolean
|
openTone3000Help: boolean,
|
||||||
|
openGuitarMlHelp: boolean
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -241,7 +244,8 @@ export default withStyles(
|
|||||||
multiSelect: false,
|
multiSelect: false,
|
||||||
selectedFiles: [],
|
selectedFiles: [],
|
||||||
//openTone3000Dialog: false,
|
//openTone3000Dialog: false,
|
||||||
openTone3000Help: false
|
openTone3000Help: false,
|
||||||
|
openGuitarMlHelp: false
|
||||||
};
|
};
|
||||||
this.requestScroll = true;
|
this.requestScroll = true;
|
||||||
}
|
}
|
||||||
@@ -1057,6 +1061,15 @@ export default withStyles(
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
handleGuitarMlHelp(e: React.MouseEvent<HTMLButtonElement>) {
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
this.setState({ openGuitarMlHelp: true });
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
handleTone3000Help(e: React.MouseEvent<HTMLButtonElement>) {
|
handleTone3000Help(e: React.MouseEvent<HTMLButtonElement>) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -1068,6 +1081,7 @@ export default withStyles(
|
|||||||
render() {
|
render() {
|
||||||
const isTracksDirectory = this.isTracksDirectory();
|
const isTracksDirectory = this.isTracksDirectory();
|
||||||
const isToobNamModelFile = this.props.fileProperty.patchProperty === ToobNamModelFileUrl;
|
const isToobNamModelFile = this.props.fileProperty.patchProperty === ToobNamModelFileUrl;
|
||||||
|
const isToobMLModelFile = this.props.fileProperty.patchProperty === ToobMlModelFileUrl;
|
||||||
|
|
||||||
const classes = withStyles.getClasses(this.props);
|
const classes = withStyles.getClasses(this.props);
|
||||||
let columnWidth = this.state.columnWidth;
|
let columnWidth = this.state.columnWidth;
|
||||||
@@ -1487,26 +1501,46 @@ export default withStyles(
|
|||||||
</DialogContent>
|
</DialogContent>
|
||||||
{(!this.state.reordering && !this.state.multiSelect) && (
|
{(!this.state.reordering && !this.state.multiSelect) && (
|
||||||
<>
|
<>
|
||||||
<DialogActions style={{ justifyContent: "stretch" }}>
|
<DialogActions style={{ justifyContent: "stretch", width: "100%" }}>
|
||||||
|
<div style={{display: "flex", flexFlow: "column nowrap", width: "100%", alignItems: "stretch", }}>
|
||||||
|
{isToobNamModelFile && (
|
||||||
|
<div style={{
|
||||||
|
display: "flex", flexFlow: "row nowrap", justifyContent: "center",
|
||||||
|
alignItems: "center", width: "100%"
|
||||||
|
}}>
|
||||||
|
<Typography variant="body2" >
|
||||||
|
Download model files from <LinkEx
|
||||||
|
href="https://www.tone3000.com/search" target="_blank">TONE3000</LinkEx>
|
||||||
|
</Typography>
|
||||||
|
<IconButtonEx tooltip="Help"
|
||||||
|
onClick={(e) => { this.handleTone3000Help(e); }} aria-label="help" edge="end" color="inherit" style={{ opacity: 0.6, marginLeft: 8 }}
|
||||||
|
>
|
||||||
|
<HelpOutlineIcon />
|
||||||
|
</IconButtonEx>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
)}
|
||||||
|
{isToobMLModelFile && (
|
||||||
|
<div style={{
|
||||||
|
display: "flex", flexFlow: "row nowrap", justifyContent: "center", width: "100%",
|
||||||
|
alignItems: "center"
|
||||||
|
}}>
|
||||||
|
<Typography variant="body2" >
|
||||||
|
Download model files from <LinkEx
|
||||||
|
href="https://github.com/GuitarML/ToneLibrary/releases/download/v1.0/Proteus_Tone_Packs.zip" target="_blank">GuitarML</LinkEx>
|
||||||
|
</Typography>
|
||||||
|
<IconButtonEx tooltip="Help"
|
||||||
|
onClick={(e) => { this.handleGuitarMlHelp(e); }} aria-label="help" edge="end" color="inherit" style={{ opacity: 0.6, marginLeft: 8 }}
|
||||||
|
>
|
||||||
|
<HelpOutlineIcon />
|
||||||
|
</IconButtonEx>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
)}
|
||||||
|
|
||||||
|
|
||||||
{this.state.windowWidth > 500 ? (
|
{this.state.windowWidth > 500 ? (
|
||||||
<div style={{ display: "flex", width: "100%", alignItems: "center", flexFlow: "column nowrap" }}>
|
<div style={{ display: "flex", width: "100%", alignItems: "center", flexFlow: "column nowrap" }}>
|
||||||
{isToobNamModelFile && (
|
|
||||||
<div style={{
|
|
||||||
display: "flex", flexFlow: "row nowrap", justifyContent: "center",
|
|
||||||
alignItems: "center", width: "100%"
|
|
||||||
}}>
|
|
||||||
<Typography variant="body2" >
|
|
||||||
Download model files from <Link
|
|
||||||
href="https://www.tone3000.com/search" target="_blank">TONE3000</Link>
|
|
||||||
</Typography>
|
|
||||||
<IconButtonEx tooltip="Help"
|
|
||||||
onClick={(e) => { this.handleTone3000Help(e); }} aria-label="help" edge="end" color="inherit" style={{ opacity: 0.6, marginLeft: 8 }}
|
|
||||||
>
|
|
||||||
<HelpOutlineIcon />
|
|
||||||
</IconButtonEx>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
)}
|
|
||||||
|
|
||||||
<div style={{ flex: "1 1 100%", display: "flex", width: "100%", alignItems: "center", flexFlow: "row nowrap" }}>
|
<div style={{ flex: "1 1 100%", display: "flex", width: "100%", alignItems: "center", flexFlow: "row nowrap" }}>
|
||||||
<IconButtonEx style={{ visibility: (this.state.hasSelection ? "visible" : "hidden") }} aria-label="delete" component="label" color="primary"
|
<IconButtonEx style={{ visibility: (this.state.hasSelection ? "visible" : "hidden") }} aria-label="delete" component="label" color="primary"
|
||||||
@@ -1587,6 +1621,7 @@ export default withStyles(
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
</div>
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
@@ -1702,6 +1737,12 @@ export default withStyles(
|
|||||||
onClose={() => this.setState({ openTone3000Help: false })}
|
onClose={() => this.setState({ openTone3000Help: false })}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
{this.state.openGuitarMlHelp && (
|
||||||
|
<GuitarMLHelpDialog
|
||||||
|
open={this.state.openGuitarMlHelp}
|
||||||
|
onClose={() => this.setState({ openGuitarMlHelp: false })}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</DialogEx>
|
</DialogEx>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,76 @@
|
|||||||
|
import DialogEx from "./DialogEx";
|
||||||
|
import DialogTitle from "@mui/material/DialogTitle";
|
||||||
|
import DialogContent from "@mui/material/DialogContent";
|
||||||
|
import Toolbar from "@mui/material/Toolbar";
|
||||||
|
import IconButtonEx from "./IconButtonEx";
|
||||||
|
import ArrowBackIcon from "@mui/icons-material/ArrowBack";
|
||||||
|
import Typography from "@mui/material/Typography";
|
||||||
|
import Link from "@mui/material/Link";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function GuitarMlHelpDialog(props: {
|
||||||
|
open: boolean;
|
||||||
|
onClose: () => void;
|
||||||
|
}) {
|
||||||
|
const { open, onClose } = props;
|
||||||
|
return (
|
||||||
|
<DialogEx
|
||||||
|
tag="tone3000-help"
|
||||||
|
fullWidth={true}
|
||||||
|
maxWidth="sm"
|
||||||
|
onEnterKey={() => { onClose(); }}
|
||||||
|
onClose={() => { onClose(); }}
|
||||||
|
open={open}>
|
||||||
|
|
||||||
|
<DialogTitle >
|
||||||
|
<Toolbar style={{ padding: 0 }}>
|
||||||
|
<IconButtonEx
|
||||||
|
tooltip="Close"
|
||||||
|
edge="start"
|
||||||
|
color="inherit"
|
||||||
|
aria-label="cancel"
|
||||||
|
style={{ opacity: 0.6 }}
|
||||||
|
onClick={() => { onClose(); }}
|
||||||
|
>
|
||||||
|
<ArrowBackIcon style={{ width: 24, height: 24 }} />
|
||||||
|
</IconButtonEx>
|
||||||
|
|
||||||
|
<Typography id="tone3000-auth-dialog-title" noWrap component="div" sx={{ flexGrow: 1 }}>
|
||||||
|
TONE3000 Help
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
</Toolbar>
|
||||||
|
</DialogTitle>
|
||||||
|
<DialogContent>
|
||||||
|
<div style={{ display: "flex", flexFlow: "row nowrap", alignItems: "start" }}>
|
||||||
|
<div style={{ flex: "1 1 1px" }} />
|
||||||
|
<div style={{
|
||||||
|
maxWidth: 500, marginLeft: "auto", marginRight: "auto",
|
||||||
|
display: "flex", flexFlow: "column nowrap", gap: 16, alignItems: "start",
|
||||||
|
}}>
|
||||||
|
<Typography variant="body1" component="div" display="block" >
|
||||||
|
The <Link href="https://www.tone3000.com" target="_blank">GuitarML Tone Library Project</Link> provides
|
||||||
|
a substantial collection of high-quality neural amp models for use in plugins that use the ML
|
||||||
|
model file format.
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="body1" component="div" display="block">
|
||||||
|
To use GuitarML models with TooB ML, you must first download the collection of models from the Guitar ML website
|
||||||
|
by clicking on the link. This should download a file named "Proteus_Tone_Packs.zip" into your browser's Downloads directory.
|
||||||
|
You must then upload the downloaded zip file, found in your browser's Download directory to the
|
||||||
|
Pipedal server using the <em>Upload</em> button in PiPedal's file browser dialog.
|
||||||
|
PiPedal automatically extracts bundles of model files from zip archives, so manual extraction is unnecessary.
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="body1" component="div" display="block">
|
||||||
|
Please consider <Link href="https://www.patreon.com/GuitarML" target="_blank">sponsoring the GuitarML project</Link> in order to support the ongoing development of the Tone Library.
|
||||||
|
</Typography>
|
||||||
|
</div>
|
||||||
|
<div style={{ flex: "2 2 1px" }} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</DialogContent>
|
||||||
|
</DialogEx>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default GuitarMlHelpDialog;
|
||||||
@@ -70,9 +70,9 @@ export default class JackStatusView extends React.Component<JackStatusViewProps,
|
|||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div style={{
|
<div style={{
|
||||||
position: "absolute", right: 30, bottom: 0, height: 30, width: 200,
|
position: "absolute", right: 30, bottom: 2,left: 30, height: 30,
|
||||||
paddingRight: 20, paddingBottom: 6,
|
paddingRight: 20, paddingBottom: 6,
|
||||||
textAlign: "right", opacity: 0.7, whiteSpace: "nowrap", fontSize: 12, zIndex: 10, fontWeight: 900
|
textAlign: "center", opacity: 0.7, whiteSpace: "nowrap", fontSize: 12, zIndex: 10, fontWeight: 900
|
||||||
}}>
|
}}>
|
||||||
{JackHostStatus.getDisplayView("",this.state.jackStatus) }
|
{JackHostStatus.getDisplayView("",this.state.jackStatus) }
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025 Robin E. R. Davies
|
||||||
|
* All rights reserved.
|
||||||
|
|
||||||
|
* 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 Link, {LinkProps} from '@mui/material/Link';
|
||||||
|
import {PiPedalModel,PiPedalModelFactory} from './PiPedalModel';
|
||||||
|
|
||||||
|
export interface LinkExProps extends LinkProps {
|
||||||
|
|
||||||
|
}
|
||||||
|
function LinkEx(props: LinkExProps) {
|
||||||
|
const { href, ...rest } = props;
|
||||||
|
|
||||||
|
function handleClick(event: React.MouseEvent<HTMLSpanElement, MouseEvent>) {
|
||||||
|
const model:PiPedalModel = PiPedalModelFactory.getInstance();
|
||||||
|
|
||||||
|
// Prevent default behavior if needed
|
||||||
|
if (model.isAndroidHosted()) {
|
||||||
|
model.androidHost?.launchExternalUrl(href as string);
|
||||||
|
} else {
|
||||||
|
window.open(href as string, '_blank', 'noopener,noreferrer');
|
||||||
|
}
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<Link onClick={(e: React.MouseEvent<HTMLSpanElement, MouseEvent>)=>{ handleClick(e); }} component="span"
|
||||||
|
{...rest} />
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default LinkEx;
|
||||||
@@ -79,6 +79,7 @@ interface PerformanceViewState {
|
|||||||
presets: PresetIndex;
|
presets: PresetIndex;
|
||||||
banks: BankIndex;
|
banks: BankIndex;
|
||||||
showSnapshotEditor: boolean;
|
showSnapshotEditor: boolean;
|
||||||
|
showStatusMonitor: boolean;
|
||||||
snapshotEditorIndex: number;
|
snapshotEditorIndex: number;
|
||||||
presetModified: boolean;
|
presetModified: boolean;
|
||||||
}
|
}
|
||||||
@@ -100,15 +101,24 @@ export const PerformanceView =
|
|||||||
banks: this.model.banks.get(),
|
banks: this.model.banks.get(),
|
||||||
wrapSelects: false,
|
wrapSelects: false,
|
||||||
showSnapshotEditor: false,
|
showSnapshotEditor: false,
|
||||||
|
showStatusMonitor: this.model.showStatusMonitor.get(),
|
||||||
snapshotEditorIndex: 0,
|
snapshotEditorIndex: 0,
|
||||||
presetModified: this.model.presetChanged.get()
|
presetModified: this.model.presetChanged.get()
|
||||||
};
|
};
|
||||||
this.onPresetsChanged = this.onPresetsChanged.bind(this);
|
this.onPresetsChanged = this.onPresetsChanged.bind(this);
|
||||||
this.onBanksChanged = this.onBanksChanged.bind(this);
|
this.onBanksChanged = this.onBanksChanged.bind(this);
|
||||||
this.onPresetChangedChanged = this.onPresetChangedChanged.bind(this);
|
this.onPresetChangedChanged = this.onPresetChangedChanged.bind(this);
|
||||||
|
this.showStatusMonitorHandler = this.showStatusMonitorHandler.bind(this);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
showStatusMonitorHandler() {
|
||||||
|
this.setState({
|
||||||
|
showStatusMonitor: this.model.showStatusMonitor.get()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
getTag() { return "performView"}
|
getTag() { return "performView"}
|
||||||
isOpen() { return this.props.open }
|
isOpen() { return this.props.open }
|
||||||
onDialogStackClose() {
|
onDialogStackClose() {
|
||||||
@@ -156,6 +166,8 @@ export const PerformanceView =
|
|||||||
this.model.presets.addOnChangedHandler(this.onPresetsChanged);
|
this.model.presets.addOnChangedHandler(this.onPresetsChanged);
|
||||||
this.model.banks.addOnChangedHandler(this.onBanksChanged);
|
this.model.banks.addOnChangedHandler(this.onBanksChanged);
|
||||||
this.model.presetChanged.addOnChangedHandler(this.onPresetChangedChanged)
|
this.model.presetChanged.addOnChangedHandler(this.onPresetChangedChanged)
|
||||||
|
this.model.showStatusMonitor.addOnChangedHandler(this.showStatusMonitorHandler);
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
presets: this.model.presets.get(),
|
presets: this.model.presets.get(),
|
||||||
banks: this.model.banks.get(),
|
banks: this.model.banks.get(),
|
||||||
@@ -173,6 +185,8 @@ export const PerformanceView =
|
|||||||
this.model.presetChanged.removeOnChangedHandler(this.onPresetChangedChanged)
|
this.model.presetChanged.removeOnChangedHandler(this.onPresetChangedChanged)
|
||||||
this.model.presets.removeOnChangedHandler(this.onPresetsChanged);
|
this.model.presets.removeOnChangedHandler(this.onPresetsChanged);
|
||||||
this.model.banks.removeOnChangedHandler(this.onBanksChanged);
|
this.model.banks.removeOnChangedHandler(this.onBanksChanged);
|
||||||
|
this.model.banks.removeOnChangedHandler(this.showStatusMonitorHandler);
|
||||||
|
|
||||||
|
|
||||||
this.mounted = false;
|
this.mounted = false;
|
||||||
this.updateHooks();
|
this.updateHooks();
|
||||||
@@ -394,9 +408,9 @@ export const PerformanceView =
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
{!this.state.showSnapshotEditor && (
|
{!this.state.showSnapshotEditor && this.state.showStatusMonitor && (
|
||||||
<JackStatusView />)
|
<JackStatusView />
|
||||||
}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{this.state.showSnapshotEditor && (
|
{this.state.showSnapshotEditor && (
|
||||||
<SnapshotEditor snapshotIndex={this.state.snapshotEditorIndex}
|
<SnapshotEditor snapshotIndex={this.state.snapshotEditorIndex}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import ObservableEvent from './ObservableEvent';
|
|||||||
import { ObservableProperty } from './ObservableProperty';
|
import { ObservableProperty } from './ObservableProperty';
|
||||||
import { Pedalboard, PedalboardItem, ControlValue, Snapshot } from './Pedalboard'
|
import { Pedalboard, PedalboardItem, ControlValue, Snapshot } from './Pedalboard'
|
||||||
import PluginClass from './PluginClass';
|
import PluginClass from './PluginClass';
|
||||||
|
import ScreenOrientation from './ScreenOrientation';
|
||||||
import PiPedalSocket, { PiPedalMessageHeader } from './PiPedalSocket';
|
import PiPedalSocket, { PiPedalMessageHeader } from './PiPedalSocket';
|
||||||
import { nullCast } from './Utility'
|
import { nullCast } from './Utility'
|
||||||
import { JackConfiguration, JackChannelSelection } from './Jack';
|
import { JackConfiguration, JackChannelSelection } from './Jack';
|
||||||
@@ -82,6 +83,59 @@ export enum ReconnectReason {
|
|||||||
HotspotChanging
|
HotspotChanging
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export class HostVersion {
|
||||||
|
constructor(hostVersion: string) {
|
||||||
|
this.versionString = hostVersion;
|
||||||
|
|
||||||
|
let pos = hostVersion.indexOf(":");
|
||||||
|
|
||||||
|
let remainder: string;
|
||||||
|
if (pos >= 0) {
|
||||||
|
this.hostName = hostVersion.substring(0, pos).trim();
|
||||||
|
remainder = hostVersion.substring(pos + 1).trim();
|
||||||
|
} else {
|
||||||
|
this.hostName = "Unknown Host";
|
||||||
|
remainder = "v0.0.0";
|
||||||
|
}
|
||||||
|
|
||||||
|
const args = remainder.split(","); // make make provisions for more.
|
||||||
|
if (args.length >= 1)
|
||||||
|
{
|
||||||
|
let versionString = args[0].trim();
|
||||||
|
if (versionString.startsWith('v')) {
|
||||||
|
versionString = versionString.substring(1).trim();
|
||||||
|
}
|
||||||
|
let releaseTypePos = versionString.indexOf("-");
|
||||||
|
if (releaseTypePos >= 0) {
|
||||||
|
this.releaseType = versionString.substring(releaseTypePos + 1).trim();
|
||||||
|
versionString = versionString.substring(0, releaseTypePos).trim();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.releaseType = "Release";
|
||||||
|
}
|
||||||
|
|
||||||
|
const parts = args[0].split(".");
|
||||||
|
if (parts.length >= 3) {
|
||||||
|
this.majorVersion = parseInt(parts[0]);
|
||||||
|
this.minorVersion = parseInt(parts[1]);
|
||||||
|
this.buildNumber = parseInt(parts[2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lessThan(major: number, minor: number, build: number): boolean {
|
||||||
|
if (this.majorVersion < major) return true;
|
||||||
|
if (this.majorVersion > major) return false;
|
||||||
|
if (this.minorVersion < minor) return true;
|
||||||
|
if (this.minorVersion > minor) return false;
|
||||||
|
return this.buildNumber < build;
|
||||||
|
}
|
||||||
|
versionString: string = "";
|
||||||
|
hostName: string = "";
|
||||||
|
releaseType: string = "";
|
||||||
|
majorVersion: number = 0;
|
||||||
|
minorVersion: number = 0;
|
||||||
|
buildNumber: number = 0;
|
||||||
|
}
|
||||||
export type PedalboardItemEnabledChangeCallback = (instanceId: number, isEnabled: boolean) => void;
|
export type PedalboardItemEnabledChangeCallback = (instanceId: number, isEnabled: boolean) => void;
|
||||||
interface PedalboardItemEnabledChangeItem {
|
interface PedalboardItemEnabledChangeItem {
|
||||||
handle: number;
|
handle: number;
|
||||||
@@ -440,6 +494,12 @@ export class PiPedalModel //implements PiPedalModel
|
|||||||
|
|
||||||
hasTone3000Auth: ObservableProperty<boolean> = new ObservableProperty<boolean>(false);
|
hasTone3000Auth: ObservableProperty<boolean> = new ObservableProperty<boolean>(false);
|
||||||
|
|
||||||
|
canKeepScreenOn: boolean = false;
|
||||||
|
keepScreenOn: ObservableProperty<boolean> = new ObservableProperty<boolean>(false);
|
||||||
|
|
||||||
|
canSetScreenOrientation: boolean = false;
|
||||||
|
screenOrientation: ObservableProperty<ScreenOrientation> = new ObservableProperty<ScreenOrientation>(ScreenOrientation.SystemDefault);
|
||||||
|
|
||||||
hasWifiDevice: ObservableProperty<boolean> = new ObservableProperty<boolean>(false);
|
hasWifiDevice: ObservableProperty<boolean> = new ObservableProperty<boolean>(false);
|
||||||
onSnapshotModified: ObservableEvent<SnapshotModifiedEvent> = new ObservableEvent<SnapshotModifiedEvent>();
|
onSnapshotModified: ObservableEvent<SnapshotModifiedEvent> = new ObservableEvent<SnapshotModifiedEvent>();
|
||||||
|
|
||||||
@@ -504,6 +564,7 @@ export class PiPedalModel //implements PiPedalModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
androidHost?: AndroidHostInterface;
|
androidHost?: AndroidHostInterface;
|
||||||
|
hostVersion?: HostVersion;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.androidHost = (window as any).AndroidHost as AndroidHostInterface;
|
this.androidHost = (window as any).AndroidHost as AndroidHostInterface;
|
||||||
@@ -1295,6 +1356,17 @@ export class PiPedalModel //implements PiPedalModel
|
|||||||
.then((succeeded) => {
|
.then((succeeded) => {
|
||||||
if (succeeded) {
|
if (succeeded) {
|
||||||
this.state.set(State.Ready);
|
this.state.set(State.Ready);
|
||||||
|
if (this.androidHost) {
|
||||||
|
this.hostVersion = new HostVersion(this.androidHost.getHostVersion());
|
||||||
|
if (!this.hostVersion.lessThan(1,1,16))
|
||||||
|
{
|
||||||
|
this.androidHost.setServerVersion(this.serverVersion?.serverVersion??"");
|
||||||
|
this.canKeepScreenOn = true;
|
||||||
|
this.keepScreenOn.set(this.androidHost.getKeepScreenOn())
|
||||||
|
this.canSetScreenOrientation = true;
|
||||||
|
this.screenOrientation.set(this.androidHost.getScreenOrientation())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
@@ -3412,6 +3484,27 @@ export class PiPedalModel //implements PiPedalModel
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setKeepScreenOn(keepScreenOn: boolean): void {
|
||||||
|
if (this.canKeepScreenOn) {
|
||||||
|
this.keepScreenOn.set(keepScreenOn);
|
||||||
|
if (this.androidHost) {
|
||||||
|
this.androidHost.setKeepScreenOn(keepScreenOn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
getKeepScreenOn(): boolean {
|
||||||
|
return this.keepScreenOn.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
getScreenOrientation(): ScreenOrientation {
|
||||||
|
return this.screenOrientation.get();
|
||||||
|
}
|
||||||
|
setScreenOrientation(value: ScreenOrientation) {
|
||||||
|
if (this.canSetScreenOrientation) {
|
||||||
|
this.screenOrientation.set(value);
|
||||||
|
this.androidHost?.setScreenOrientation(value as number);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let instance: PiPedalModel | undefined = undefined;
|
let instance: PiPedalModel | undefined = undefined;
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025 Robin E. R. Davies
|
||||||
|
* All rights reserved.
|
||||||
|
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
enum ScreenOrientation {
|
||||||
|
// values must match Pipedal Remote ScreenOrientation.java
|
||||||
|
SystemDefault = 0,
|
||||||
|
Landscape = 1,
|
||||||
|
Portrait = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ScreenOrientation;
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
// 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 List from '@mui/material/List';
|
||||||
|
import ListItemText from '@mui/material/ListItemText';
|
||||||
|
import DialogEx from './DialogEx';
|
||||||
|
|
||||||
|
import { ListItemButton } from '@mui/material';
|
||||||
|
import ScreenOrientation from './ScreenOrientation';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export interface SelectScreenOrientationDialogProps {
|
||||||
|
open: boolean;
|
||||||
|
screenOrientation: ScreenOrientation;
|
||||||
|
onClose: (screenOrientation: ScreenOrientation | null) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function SelectScreenOrientationDialog(props: SelectScreenOrientationDialogProps) {
|
||||||
|
//const classes = useStyles();
|
||||||
|
const { onClose, screenOrientation, open } = props;
|
||||||
|
|
||||||
|
const handleCancel = () => {
|
||||||
|
onClose(null);
|
||||||
|
}
|
||||||
|
const handleOk = (value: ScreenOrientation) => {
|
||||||
|
onClose(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleListItemClick = (value: ScreenOrientation) => {
|
||||||
|
handleOk(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DialogEx tag="channels" onClose={handleCancel} aria-labelledby="select-channels-title" open={open}
|
||||||
|
onEnterKey={() => { }}
|
||||||
|
>
|
||||||
|
|
||||||
|
<List style={{ marginLeft: 0, marginRight: 0 }}>
|
||||||
|
<ListItemButton onClick={() => handleListItemClick(ScreenOrientation.SystemDefault)} key={"0"}
|
||||||
|
selected={screenOrientation === ScreenOrientation.SystemDefault} >
|
||||||
|
<ListItemText primary={"System default"} />
|
||||||
|
</ListItemButton>
|
||||||
|
<ListItemButton onClick={() => handleListItemClick(ScreenOrientation.Portrait)} key={"1"}
|
||||||
|
selected={screenOrientation === ScreenOrientation.Portrait} >
|
||||||
|
<ListItemText primary={"Portrait"} />
|
||||||
|
</ListItemButton>
|
||||||
|
<ListItemButton onClick={() => handleListItemClick(ScreenOrientation.Landscape)} key={"2"}
|
||||||
|
selected={screenOrientation === ScreenOrientation.Landscape} >
|
||||||
|
<ListItemText primary={"Landscape"} />
|
||||||
|
</ListItemButton>
|
||||||
|
</List>
|
||||||
|
</DialogEx>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SelectScreenOrientationDialog;
|
||||||
@@ -46,10 +46,10 @@ import DialogEx from './DialogEx'
|
|||||||
import GovernorSettings from './GovernorSettings';
|
import GovernorSettings from './GovernorSettings';
|
||||||
import SystemMidiBindingsDialog from './SystemMidiBindingsDialog';
|
import SystemMidiBindingsDialog from './SystemMidiBindingsDialog';
|
||||||
import SelectThemeDialog from './SelectThemeDialog';
|
import SelectThemeDialog from './SelectThemeDialog';
|
||||||
import {AlsaSequencerConfiguration} from './AlsaSequencer';
|
import { AlsaSequencerConfiguration } from './AlsaSequencer';
|
||||||
|
|
||||||
import Slide, { SlideProps } from '@mui/material/Slide';
|
import Slide, { SlideProps } from '@mui/material/Slide';
|
||||||
import {createStyles} from './WithStyles';
|
import { createStyles } from './WithStyles';
|
||||||
|
|
||||||
import { Theme } from '@mui/material/styles';
|
import { Theme } from '@mui/material/styles';
|
||||||
import { withStyles } from "tss-react/mui";
|
import { withStyles } from "tss-react/mui";
|
||||||
@@ -57,6 +57,8 @@ import WithStyles from './WithStyles';
|
|||||||
import { canScaleWindow, getWindowScaleOptions, getWindowScaleText, setWindowScale, getWindowScale } from './WindowScale';
|
import { canScaleWindow, getWindowScaleOptions, getWindowScaleText, setWindowScale, getWindowScale } from './WindowScale';
|
||||||
import OptionsDialog from './OptionsDialog';
|
import OptionsDialog from './OptionsDialog';
|
||||||
import { css } from '@emotion/react';
|
import { css } from '@emotion/react';
|
||||||
|
import ScreenOrientation from './ScreenOrientation';
|
||||||
|
import SelectScreenOrientationDialog from './SelectScreenOrientationDialog';
|
||||||
|
|
||||||
|
|
||||||
interface SettingsDialogProps extends WithStyles<typeof styles> {
|
interface SettingsDialogProps extends WithStyles<typeof styles> {
|
||||||
@@ -74,6 +76,8 @@ interface SettingsDialogState {
|
|||||||
jackSettings: JackChannelSelection;
|
jackSettings: JackChannelSelection;
|
||||||
jackServerSettings: JackServerSettings;
|
jackServerSettings: JackServerSettings;
|
||||||
alsaSequencerConfiguration: AlsaSequencerConfiguration;
|
alsaSequencerConfiguration: AlsaSequencerConfiguration;
|
||||||
|
keepScreenOn: boolean;
|
||||||
|
screenOrientation: ScreenOrientation;
|
||||||
|
|
||||||
jackStatus?: JackHostStatus;
|
jackStatus?: JackHostStatus;
|
||||||
governorSettings: GovernorSettings;
|
governorSettings: GovernorSettings;
|
||||||
@@ -88,6 +92,7 @@ interface SettingsDialogState {
|
|||||||
showGovernorSettingsDialog: boolean;
|
showGovernorSettingsDialog: boolean;
|
||||||
showInputSelectDialog: boolean;
|
showInputSelectDialog: boolean;
|
||||||
showOutputSelectDialog: boolean;
|
showOutputSelectDialog: boolean;
|
||||||
|
showScreenOrientationDialog: boolean;
|
||||||
showMidiSelectDialog: boolean;
|
showMidiSelectDialog: boolean;
|
||||||
showThemeSelectDialog: boolean;
|
showThemeSelectDialog: boolean;
|
||||||
showJackServerSettingsDialog: boolean;
|
showJackServerSettingsDialog: boolean;
|
||||||
@@ -191,13 +196,15 @@ const SettingsDialog = withStyles(
|
|||||||
wifiDirectConfigSettings: this.model.wifiDirectConfigSettings.get(),
|
wifiDirectConfigSettings: this.model.wifiDirectConfigSettings.get(),
|
||||||
governorSettings: this.model.governorSettings.get(),
|
governorSettings: this.model.governorSettings.get(),
|
||||||
continueDisabled: true,
|
continueDisabled: true,
|
||||||
|
keepScreenOn: this.model.keepScreenOn.get(),
|
||||||
|
screenOrientation: this.model.getScreenOrientation(),
|
||||||
showWindowScaleDialog: false,
|
showWindowScaleDialog: false,
|
||||||
showWifiConfigDialog: false,
|
showWifiConfigDialog: false,
|
||||||
showWifiDirectConfigDialog: false,
|
showWifiDirectConfigDialog: false,
|
||||||
showGovernorSettingsDialog: false,
|
showGovernorSettingsDialog: false,
|
||||||
showInputSelectDialog: false,
|
showInputSelectDialog: false,
|
||||||
showOutputSelectDialog: false,
|
showOutputSelectDialog: false,
|
||||||
|
showScreenOrientationDialog: false,
|
||||||
showMidiSelectDialog: false,
|
showMidiSelectDialog: false,
|
||||||
showThemeSelectDialog: false,
|
showThemeSelectDialog: false,
|
||||||
showJackServerSettingsDialog: false,
|
showJackServerSettingsDialog: false,
|
||||||
@@ -219,11 +226,21 @@ const SettingsDialog = withStyles(
|
|||||||
this.handleConnectionStateChanged = this.handleConnectionStateChanged.bind(this);
|
this.handleConnectionStateChanged = this.handleConnectionStateChanged.bind(this);
|
||||||
this.handleShowStatusMonitorChanged = this.handleShowStatusMonitorChanged.bind(this);
|
this.handleShowStatusMonitorChanged = this.handleShowStatusMonitorChanged.bind(this);
|
||||||
this.handleHasWifiChanged = this.handleHasWifiChanged.bind(this);
|
this.handleHasWifiChanged = this.handleHasWifiChanged.bind(this);
|
||||||
|
this.handleKeepScreenOnChanged = this.handleKeepScreenOnChanged.bind(this);
|
||||||
|
this.handleScreenOrientationChanged = this.handleScreenOrientationChanged.bind(this);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleScreenOrientationChanged(newValue: ScreenOrientation) {
|
||||||
|
this.setState({
|
||||||
|
screenOrientation: newValue
|
||||||
|
});
|
||||||
|
}
|
||||||
|
handleKeepScreenOnChanged(newValue: boolean) {
|
||||||
|
this.setState({ keepScreenOn: newValue });
|
||||||
|
}
|
||||||
handleHasWifiChanged(newValue: boolean) {
|
handleHasWifiChanged(newValue: boolean) {
|
||||||
this.setState({hasWifiDevice: newValue});
|
this.setState({ hasWifiDevice: newValue });
|
||||||
}
|
}
|
||||||
|
|
||||||
handleShowStatusMonitorChanged(): void {
|
handleShowStatusMonitorChanged(): void {
|
||||||
@@ -337,6 +354,8 @@ const SettingsDialog = withStyles(
|
|||||||
if (active !== this.active) {
|
if (active !== this.active) {
|
||||||
this.active = active;
|
this.active = active;
|
||||||
if (active) {
|
if (active) {
|
||||||
|
this.model.keepScreenOn.addOnChangedHandler(this.handleKeepScreenOnChanged);
|
||||||
|
this.model.screenOrientation.addOnChangedHandler(this.handleScreenOrientationChanged);
|
||||||
this.model.hasWifiDevice.addOnChangedHandler(this.handleHasWifiChanged);
|
this.model.hasWifiDevice.addOnChangedHandler(this.handleHasWifiChanged);
|
||||||
this.model.state.addOnChangedHandler(this.handleConnectionStateChanged);
|
this.model.state.addOnChangedHandler(this.handleConnectionStateChanged);
|
||||||
this.model.showStatusMonitor.addOnChangedHandler(this.handleShowStatusMonitorChanged);
|
this.model.showStatusMonitor.addOnChangedHandler(this.handleShowStatusMonitorChanged);
|
||||||
@@ -368,7 +387,7 @@ const SettingsDialog = withStyles(
|
|||||||
this.handleJackServerSettingsChanged();
|
this.handleJackServerSettingsChanged();
|
||||||
this.handleWifiConfigSettingsChanged();
|
this.handleWifiConfigSettingsChanged();
|
||||||
this.handleWifiDirectConfigSettingsChanged();
|
this.handleWifiDirectConfigSettingsChanged();
|
||||||
this.setState({hasWifiDevice: this.model.hasWifiDevice.get()});
|
this.setState({ hasWifiDevice: this.model.hasWifiDevice.get() });
|
||||||
|
|
||||||
this.timerHandle = setInterval(() => this.tick(), 1000);
|
this.timerHandle = setInterval(() => this.tick(), 1000);
|
||||||
} else {
|
} else {
|
||||||
@@ -377,6 +396,8 @@ const SettingsDialog = withStyles(
|
|||||||
}
|
}
|
||||||
this.model.state.removeOnChangedHandler(this.handleConnectionStateChanged);
|
this.model.state.removeOnChangedHandler(this.handleConnectionStateChanged);
|
||||||
this.model.showStatusMonitor.removeOnChangedHandler(this.handleShowStatusMonitorChanged);
|
this.model.showStatusMonitor.removeOnChangedHandler(this.handleShowStatusMonitorChanged);
|
||||||
|
this.model.keepScreenOn.removeOnChangedHandler(this.handleKeepScreenOnChanged);
|
||||||
|
this.model.screenOrientation.removeOnChangedHandler(this.handleScreenOrientationChanged);
|
||||||
|
|
||||||
this.model.jackConfiguration.removeOnChangedHandler(this.handleJackConfigurationChanged);
|
this.model.jackConfiguration.removeOnChangedHandler(this.handleJackConfigurationChanged);
|
||||||
this.model.alsaSequencerConfiguration.removeOnChangedHandler(this.handleAlsaSequencerConfigurationChanged);
|
this.model.alsaSequencerConfiguration.removeOnChangedHandler(this.handleAlsaSequencerConfigurationChanged);
|
||||||
@@ -441,6 +462,28 @@ const SettingsDialog = withStyles(
|
|||||||
showOutputSelectDialog: false
|
showOutputSelectDialog: false
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
handleScreenOrientation() {
|
||||||
|
this.setState({
|
||||||
|
showScreenOrientationDialog: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
getOrientationText() {
|
||||||
|
switch (this.state.screenOrientation) {
|
||||||
|
case ScreenOrientation.Portrait:
|
||||||
|
return "Portrait";
|
||||||
|
case ScreenOrientation.Landscape:
|
||||||
|
return "Landscape";
|
||||||
|
default:
|
||||||
|
return "System default";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
handleScreenOrientationDialogResult(orientation: ScreenOrientation | null): void {
|
||||||
|
if (orientation !== null) {
|
||||||
|
this.setState({ screenOrientation: orientation });
|
||||||
|
this.model.setScreenOrientation(orientation);
|
||||||
|
}
|
||||||
|
this.setState({ showScreenOrientationDialog: false });
|
||||||
|
}
|
||||||
|
|
||||||
handleOutputSelection() {
|
handleOutputSelection() {
|
||||||
this.setState({
|
this.setState({
|
||||||
@@ -553,6 +596,8 @@ const SettingsDialog = withStyles(
|
|||||||
let selectedChannels: string[] = this.state.showInputSelectDialog ? this.state.jackSettings.inputAudioPorts : this.state.jackSettings.outputAudioPorts;
|
let selectedChannels: string[] = this.state.showInputSelectDialog ? this.state.jackSettings.inputAudioPorts : this.state.jackSettings.outputAudioPorts;
|
||||||
let disableShutdown = this.state.shuttingDown || this.state.restarting;
|
let disableShutdown = this.state.shuttingDown || this.state.restarting;
|
||||||
|
|
||||||
|
let canKeepScreenOn = this.model.canKeepScreenOn;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DialogEx tag="settings" fullScreen open={this.props.open}
|
<DialogEx tag="settings" fullScreen open={this.props.open}
|
||||||
onClose={() => { this.props.onClose() }} TransitionComponent={Transition}
|
onClose={() => { this.props.onClose() }} TransitionComponent={Transition}
|
||||||
@@ -730,6 +775,51 @@ const SettingsDialog = withStyles(
|
|||||||
</Typography>
|
</Typography>
|
||||||
</div>
|
</div>
|
||||||
</ButtonBase>
|
</ButtonBase>
|
||||||
|
{canKeepScreenOn &&
|
||||||
|
(
|
||||||
|
<ButtonBase
|
||||||
|
className={classes.setting}
|
||||||
|
onClick={() => {
|
||||||
|
this.model.setKeepScreenOn(!this.state.keepScreenOn)
|
||||||
|
}} >
|
||||||
|
<SelectHoverBackground selected={false} showHover={true} />
|
||||||
|
<div style={{ width: "100%" }}>
|
||||||
|
<div style={{
|
||||||
|
width: "100%", display: "flex", flexDirection: "row", flexWrap: "nowrap",
|
||||||
|
alignItems: "center", maxWidth: 400
|
||||||
|
}}>
|
||||||
|
<div style={{ flex: "1 1 auto" }}>
|
||||||
|
<Typography className={classes.primaryItem} display="block" variant="body2" color="textPrimary" noWrap>
|
||||||
|
Keep screen on.</Typography>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{ flex: "0 0 auto" }}>
|
||||||
|
<Switch
|
||||||
|
checked={this.state.keepScreenOn}
|
||||||
|
onChange={
|
||||||
|
(e) => { this.model.setKeepScreenOn(e.target.checked); }
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ButtonBase>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
{this.model.canSetScreenOrientation && (
|
||||||
|
<ButtonBase className={classes.setting} onClick={() => this.handleScreenOrientation()}
|
||||||
|
>
|
||||||
|
<SelectHoverBackground selected={false} showHover={true} />
|
||||||
|
<div style={{ width: "100%" }}>
|
||||||
|
<Typography display="block" variant="body2" noWrap>Display Orientation</Typography>
|
||||||
|
<Typography display="block" variant="caption" color="textSecondary" noWrap>{
|
||||||
|
this.getOrientationText()
|
||||||
|
}</Typography>
|
||||||
|
</div>
|
||||||
|
</ButtonBase>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
{(canScaleWindow()) &&
|
{(canScaleWindow()) &&
|
||||||
(
|
(
|
||||||
@@ -908,6 +998,21 @@ const SettingsDialog = withStyles(
|
|||||||
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
this.state.showScreenOrientationDialog &&
|
||||||
|
(
|
||||||
|
<SelectScreenOrientationDialog
|
||||||
|
open={this.state.showScreenOrientationDialog}
|
||||||
|
onClose={(screenOrientation: ScreenOrientation | null) => {
|
||||||
|
this.handleScreenOrientationDialogResult(screenOrientation);
|
||||||
|
}}
|
||||||
|
screenOrientation={this.state.screenOrientation}
|
||||||
|
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
(this.state.showGovernorSettingsDialog) &&
|
(this.state.showGovernorSettingsDialog) &&
|
||||||
(
|
(
|
||||||
|
|||||||
Reference in New Issue
Block a user