@@ -1076,6 +1299,7 @@ function ModGuiHost(props: ModGuiHostProps) {
);
}
+
function addPortClass(element: Element, selector: string, className: string) {
let children = element.querySelectorAll(selector);
// call addClass to each element that matches the selector
@@ -1091,13 +1315,13 @@ function ModGuiHost(props: ModGuiHostProps) {
pluginControl: pluginControl,
onValueChanged: (instanceId: number, symbol: string, value: number) => {
try {
- props.hostSite.setPedalboardControl(instanceId, symbol, value);
+ model.setPedalboardControl(instanceId, symbol, value);
} catch (error) {
}
},
- monitorPort: props.hostSite.monitorPort,
- unmonitorPort: props.hostSite.unmonitorPort
+ monitorPort: model.monitorPort.bind(model),
+ unmonitorPort: model.unmonitorPort.bind(model)
}
);
customSelectControl.attach(control as HTMLElement);
@@ -1108,6 +1332,20 @@ function ModGuiHost(props: ModGuiHostProps) {
}
customSelectControl.onMounted();
}
+ function monitorBypassPort(
+ instanceId: number,
+ symbol: string,
+ interval: number,
+ callback: (value: number) => void): MonitorPortHandle {
+ return model.addPedalboardItemEnabledChangeListener(
+ instanceId, (instanceId,value) => {
+ callback(value ? 1 : 0);
+ }
+ );
+ }
+ function unmonitorBypassPort(handle: MonitorPortHandle) {
+ model.removePedalboardItemEnabledChangeListener(handle as ListenHandle);
+ }
function createFootswitchControl(control: Element, symbol: string, controlType: ControlType) {
let uiControl = new UiControl();
uiControl.symbol = symbol;
@@ -1124,14 +1362,24 @@ function ModGuiHost(props: ModGuiHostProps) {
filmStrip: "/img/footswitch_strip.png",
verticalStrip: true,
onValueChanged: (instanceId: number, symbol: string, value: number) => {
- try {
- props.hostSite.setPedalboardControl(instanceId, symbol, value);
- } catch (error) {
+ if (symbol === "_bypass") {
+ model.setPedalboardItemEnabled(instanceId, value !== 0);
+ } else {
+ try {
+ model.setPedalboardControl(instanceId, symbol, value);
+ } catch (error) {
+ }
}
},
- monitorPort: props.hostSite.monitorPort,
- unmonitorPort: props.hostSite.unmonitorPort
+ monitorPort:
+ symbol === "_bypass" ?
+ monitorBypassPort :
+ model.monitorPort.bind(model),
+ unmonitorPort:
+ symbol == "_bypass" ?
+ unmonitorBypassPort :
+ model.unmonitorPort.bind(model)
}
);
filmstripControl.attach(control as HTMLElement);
@@ -1150,9 +1398,10 @@ function ModGuiHost(props: ModGuiHostProps) {
}
let selectPathControl = new CustomSelectPathControl({
instanceId: props.instanceId,
- propertyUri: pathUri,
+ propertyUri: pathUri,
plugin: props.plugin,
- hostSite: props.hostSite
+ hostSite: model,
+ handleFileSelect: props.handleFileSelect
});
selectPathControl.attach(control as HTMLElement);
@@ -1160,29 +1409,13 @@ function ModGuiHost(props: ModGuiHostProps) {
selectPathControl.onMounted();
}
-
- function createBypassLightControl(control: Element, symbol: string) {
- let uiControl = new UiControl();
- uiControl.symbol = symbol;
- uiControl.controlType = ControlType.BypassLight;
- uiControl.min_value = 0;
- uiControl.max_value = 1;
- uiControl.is_logarithmic = false;
- uiControl.integer_property = true;
+
+ function createBypassLightControl(control: Element) {
let bypassLightControl = new BypassLightControl(
{
instanceId: props.instanceId,
- pluginControl: uiControl,
- onValueChanged: (instanceId: number, symbol: string, value: number) => {
- try {
- props.hostSite.setPedalboardControl(instanceId, symbol, value);
- } catch (error) {
-
- }
- },
- monitorPort: props.hostSite.monitorPort,
- unmonitorPort: props.hostSite.unmonitorPort
+ model: model
}
);
bypassLightControl.attach(control as HTMLElement);
@@ -1211,13 +1444,13 @@ function ModGuiHost(props: ModGuiHostProps) {
verticalStrip: false,
onValueChanged: (instanceId: number, symbol: string, value: number) => {
try {
- props.hostSite.setPedalboardControl(instanceId, symbol, value);
+ model.setPedalboardControl(instanceId, symbol, value);
} catch (error) {
}
},
- monitorPort: props.hostSite.monitorPort,
- unmonitorPort: props.hostSite.unmonitorPort
+ monitorPort: model.monitorPort.bind(model),
+ unmonitorPort: model.unmonitorPort.bind(model)
}
);
@@ -1284,14 +1517,11 @@ function ModGuiHost(props: ModGuiHostProps) {
.forEach((control) => {
let symbol = "_bypass";
let controlType = ControlType.OnOffSwitch;
-
createFootswitchControl(control, symbol, controlType);
});
element.querySelectorAll('[mod-role=bypass-light]')
.forEach((control) => {
- let symbol = "_bypass";
-
- createBypassLightControl(control, symbol);
+ createBypassLightControl(control);
});
element.querySelectorAll('[mod-role=input-parameter]')
.forEach((control) => {
@@ -1303,6 +1533,7 @@ function ModGuiHost(props: ModGuiHostProps) {
setErrorMessage(ModMessage(message));
}
async function requestContent() {
+ updateContentReady(false);
try {
let modGui = plugin.modGui;
if (!modGui) {
@@ -1321,7 +1552,7 @@ function ModGuiHost(props: ModGuiHostProps) {
let encodedUri = encodeURIComponent(props.plugin.uri);
let version = props.plugin.minorVersion * 1000 + props.plugin.microVersion;
- let resourceUrl = xmodel.modResourcesUrl;
+ let resourceUrl = model.modResourcesUrl;
let queryParams = "?ns=" + encodedUri + "&v=" + version.toString();
let templateUri = resourceUrl + "_/iconTemplate" + queryParams;
let cssUri = resourceUrl + "_/stylesheet" + queryParams;
@@ -1367,6 +1598,7 @@ function ModGuiHost(props: ModGuiHostProps) {
let height = element.clientHeight;
hostDivRef.style.width = width + "px";
hostDivRef.style.height = height + "px";
+ updateContentReady(true);
} catch (error) {
setModError("Error loading UI: " + (error instanceof Error ? error.message : String(error)));
}
@@ -1383,9 +1615,12 @@ function ModGuiHost(props: ModGuiHostProps) {
let stateHandler = (state: State) => {
setReady(state === State.Ready);
}
- xmodel.state.addOnChangedHandler(stateHandler)
+ model.state.addOnChangedHandler(stateHandler)
+
+
return () => {
- xmodel.state.removeOnChangedHandler(stateHandler);
+ model.state.removeOnChangedHandler(stateHandler);
+
if (tHostDivRef !== null) {
// unmount the custom content.
let children = tHostDivRef.children;
@@ -1396,6 +1631,7 @@ function ModGuiHost(props: ModGuiHostProps) {
}
}
}
+ updateContentReady(false);
let mc = modGuiControls;
for (let i = 0; i < mc.length; i++) {
let modGuiControl = mc[i];
@@ -1405,12 +1641,12 @@ function ModGuiHost(props: ModGuiHostProps) {
};
}, [hostDivRef, plugin, ready]);
+
return (
{ props.onClose(); setErrorMessage(null); }}>
{
@@ -1418,14 +1654,14 @@ function ModGuiHost(props: ModGuiHostProps) {
event.stopPropagation();
}}
>
-
onClose()} style={{
- position: "absolute", top: 16, right: 16,
- background: "#FFF5", zIndex: 600
- }}>
-
-
-
-
+ {maximizedUi && (
+
onClose()} style={{
+ position: "absolute", top: 16, right: 16,
+ background: "#FFF5", zIndex: 600
+ }}>
+
+
+ )}
-
-
- {
- setErrorMessage(null);
- onClose();
- }}
- text={errorMessage ?? ""}
- />
+ {errorMessage !== null && (
+ {
+ setErrorMessage(null);
+ onClose();
+ }}
+ text={errorMessage ?? ""}
+ />
+ )}
+
);
}
+
+interface ModGuiPluginPreference {
+ pluginUri: string;
+ useModGui: boolean;
+}
+
+let modGuiPluginPreferences: ModGuiPluginPreference[] | null = null;
+
+
+function loadModGuiPreferences() {
+ if (modGuiPluginPreferences === null) {
+ let prefs = window.localStorage.getItem("modGuiPluginPreferences");
+ try {
+ if (prefs) {
+ modGuiPluginPreferences = JSON.parse(prefs);
+ } else {
+ modGuiPluginPreferences = [];
+ }
+ } catch (error) {
+ console.error("pipedal: Error parsing modGuiPluginPreferences from localStorage: " + String(error));
+ modGuiPluginPreferences = [];
+ }
+ }
+}
+
+export function getDefaultModGuiPreference(pluginUri: string) {
+ loadModGuiPreferences();
+ if (modGuiPluginPreferences === null) {
+ modGuiPluginPreferences = [];
+ }
+ if (modGuiPluginPreferences) {
+ let preference = modGuiPluginPreferences.find(p => p.pluginUri === pluginUri);
+ if (preference) {
+ return preference.useModGui;
+ }
+ }
+ return false;
+}
+
+
+export function setDefaultModGuiPreference(pluginUri: string, useModGui: boolean) {
+ loadModGuiPreferences();
+ if (modGuiPluginPreferences === null) {
+ modGuiPluginPreferences = [];
+ }
+
+ let preference = modGuiPluginPreferences.find(p => p.pluginUri === pluginUri);
+ if (preference) {
+ preference.useModGui = useModGui;
+ } else {
+ modGuiPluginPreferences.push({ pluginUri: pluginUri, useModGui });
+ }
+ try {
+ window.localStorage.setItem("modGuiPluginPreferences", JSON.stringify(modGuiPluginPreferences));
+ } catch(error) {
+ console.error("pipedal: Error saving modGuiPluginPreferences to localStorage: " + String(error));
+ }
+}
+
+
export default ModGuiHost;
\ No newline at end of file
diff --git a/vite/src/pipedal/ModGuiTest.tsx b/vite/src/pipedal/ModGuiTest.tsx
deleted file mode 100644
index 1e0d616..0000000
--- a/vite/src/pipedal/ModGuiTest.tsx
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * 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,
- * 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 from 'react';
-import Divider from '@mui/material/Divider';
-import { PiPedalModel, PiPedalModelFactory, MonitorPortHandle, State, ListenHandle, PatchPropertyListener } from './PiPedalModel';
-import { useTheme } from '@mui/material/styles';
-import CircularProgress from '@mui/material/CircularProgress';
-import LoadPluginDialog from './LoadPluginDialog';
-import ButtonEx from './ButtonEx';
-import Typography from '@mui/material/Typography/Typography';
-import ModGuiHost, { IModGuiHostSite } from './ModGuiHost';
-import { UiPlugin } from './Lv2Plugin';
-import ModGuiErrorBoundary from './ModGuiErrorBoundary';
-
-class MyPortHandle implements MonitorPortHandle {
- private static nextHandle: number = 1;
- constructor() {
- this.handle = MyPortHandle.nextHandle++;
- }
- handle: number;
-};
-
-type MonitorCallback = (value: number) => void;
-
-class ValueEntry {
- constructor(defaultValue: number) {
- this.value = defaultValue;
- }
- private listeners: { [handle: number]: MonitorCallback } = {};
-
- monitor(interval: number, callback: MonitorCallback): MyPortHandle {
- let handle = new MyPortHandle();
- this.listeners[handle.handle] = callback;
- return handle;
- }
- unmonitor(handle: MonitorPortHandle) {
- let h = (handle as MyPortHandle).handle;
- // remove entry h from listeners
- if (!(h in this.listeners)) {
- throw new Error("Invalid handle: " + h);
- }
- // remove the callback from the listeners
- delete this.listeners[h];
- }
- setValue(value: number) {
- if (value !== this.value) {
- this.value = value;
- // notify all listeners
- for (let handle in this.listeners) {
- this.listeners[handle](value);
- }
- }
- }
- value: number;
-};
-
-class PatchListenerEntry {
- constructor(instanceId: number, propertyUri: string) {
- this.instanceId = instanceId;
- this.propertyUri = propertyUri;
- }
- instanceId: number;
- propertyUri: string;
- value: any = "";
- listeners: { handle: number, listener: PatchPropertyListener}[] = [];;
-};
-
-
-class ValueHandler {
-
- private valueDictionary: { [symbol: string]: ValueEntry } = {};
- private handleToValueEnry: { [handle: number]: ValueEntry } = {};
-
- constructor(instanceId: number, plugin: UiPlugin) {
- for (let control of plugin.controls) {
- this.valueDictionary[control.symbol] = new ValueEntry(control.default_value);
- }
- this.valueDictionary["_bypass"] = new ValueEntry(0);
- }
- monitorPort(instanceId: number, symbol: string, interval: number, callback: MonitorCallback): MonitorPortHandle {
- let valueEntry = this.valueDictionary[symbol];
-
- let portHandle = valueEntry.monitor(interval, callback);
- this.handleToValueEnry[(portHandle as MyPortHandle).handle] = valueEntry;
- callback(valueEntry.value);
- return portHandle;
- }
- unmonitorPort(handle: MonitorPortHandle): void {
- let h = (handle as MyPortHandle).handle;
- if (!(h in this.handleToValueEnry)) {
- throw new Error("Invalid handle: " + h);
- }
- let valueEntry = this.handleToValueEnry[h];
- valueEntry.unmonitor(handle);
- delete this.handleToValueEnry[h];
- }
- setValue(instanceId: number, symbol: string, value: number) {
- // add a delay just for funsies.
- window.setTimeout(() => {
- if (!(symbol in this.valueDictionary)) {
- throw new Error("Invalid symbol: " + symbol);
- }
- let valueEntry = this.valueDictionary[symbol];
- valueEntry.setValue(value);
- }, 100);
- }
- getValue(instanceId: number, symbol: string): number {
- if (!(symbol in this.valueDictionary)) {
- throw new Error("Invalid symbol: " + symbol);
- }
- let valueEntry = this.valueDictionary[symbol];
- return valueEntry.value;
- }
- private nextListenHandle: number = 1;
-
-
- private patchListeners: PatchListenerEntry[] = [];
-
- monitorPatchProperty(instanceId: number, propertyUri: string, onReceived: PatchPropertyListener): ListenHandle {
- let h = this.nextListenHandle++;
- for (let entry of this.patchListeners) {
- if (entry.instanceId === instanceId && entry.propertyUri === propertyUri) {
- // already listening to this property
- entry.listeners.push({ handle: h, listener: onReceived });
- onReceived(instanceId,propertyUri,entry.value);
- return { _handle: h };
- }
- }
- let entry = new PatchListenerEntry(instanceId, propertyUri);
- this.patchListeners.push(entry);
- entry.listeners.push({ handle: h, listener: onReceived });
- onReceived(instanceId, propertyUri, entry.value);
- return {_handle: h};
- }
- cancelMonitorPatchProperty(listenHandle: ListenHandle): void {
- for (let i = 0; i < this.patchListeners.length; ++i) {
- let entry = this.patchListeners[i];
- for (let j = 0; j < entry.listeners.length; ++j) {
- if (entry.listeners[j].handle === listenHandle._handle) {
- // found the listener, remove it
- entry.listeners.splice(j, 1);
- if (entry.listeners.length === 0) {
- // no more listeners, remove the entry
- this.patchListeners.splice(i, 1);
- }
- return;
- }
- }
- }
- }
- getPatchProperty(instanceId: number, uri: string): Promise
{
- let promise = new Promise((resolve, reject) => {
- window.setTimeout(() => {
- for (let entry of this.patchListeners) {
- if (entry.instanceId === instanceId && entry.propertyUri === uri) {
- window.setTimeout(() => {
- // simulate a delay for getting the property
- entry.listeners.forEach(l => l.listener(instanceId, uri, entry.value));
- }, 100);
- return resolve(entry.value);
- }
- }
- reject(new Error(`Patch property not found: ${uri} for instance ${instanceId}`));
- },50);
- });
- return promise;
- }
- setPatchProperty(instanceId: number, uri: string, value: any): Promise {
- // Implementation here
- for (let entry of this.patchListeners) {
- if (entry.instanceId === instanceId && entry.propertyUri === uri) {
- entry.value = value;
- // notify all listeners
- entry.listeners.forEach(l => l.listener(instanceId, uri, value));
- return Promise.resolve(true);
- }
- }
- // if we reach here, the property was not found
- return Promise.reject("Not found.");
- }
-};
-
-function ModGuiTest() {
- const [pluginUrl, setPluginUrl] = React.useState("");
- const [uiPlugin, setUiPlugin] = React.useState(null);
- const [pluginDialogOpen, setPluginDialogOpen] = React.useState(false);
- const [loading, setLoading] = React.useState(true);
- const [valueHandler, setValueHandler] = React.useState(null);
-
- const [modGuiHostSite] = React.useState({
- monitorPort: (instanceId: number, symbol: string, interval: number, callback: (value: number) => void) => {
- if (!valueHandler) {
- throw new Error("ValueHandler is not set");
- }
- return valueHandler.monitorPort(instanceId, symbol, interval, callback);
- },
- unmonitorPort: (handle) => {
- if (!valueHandler) {
- throw new Error("ValueHandler is not set");
- }
- valueHandler.unmonitorPort(handle);
- },
- setPedalboardControl: (instanceId, symbol, value) => {
- if (!valueHandler) {
- throw new Error("ValueHandler is not set");
- }
- valueHandler.setValue(instanceId, symbol, value);
- },
- monitorPatchProperty(instanceId: number, propertyUri: string, onReceived: PatchPropertyListener): ListenHandle {
- if (!valueHandler) {
- throw new Error("ValueHandler is not set");
- }
-
- return valueHandler.monitorPatchProperty(instanceId, propertyUri, onReceived);
- },
- cancelMonitorPatchProperty: (listenHandle) => {
- if (!valueHandler) {
- throw new Error("ValueHandler is not set");
- }
- valueHandler.cancelMonitorPatchProperty(listenHandle);
- },
- getPatchProperty: async (instanceId, uri) => {
- if (!valueHandler) {
- throw new Error("ValueHandler is not set");
- }
- return valueHandler.getPatchProperty(instanceId, uri) as Promise;
- },
- setPatchProperty: async (instanceId, uri, value) => {
- if (!valueHandler) {
- throw new Error("ValueHandler is not set");
- }
- return valueHandler.setPatchProperty(instanceId, uri, value) as Promise;
- }
- });
-
- let model: PiPedalModel = PiPedalModelFactory.getInstance();
-
- React.useEffect(() => {
-
- const onStateChange = (state: State) => {
- if (state == State.Ready) {
- setLoading(false);
- }
- };
-
- model.state.addOnChangedHandler(onStateChange);
-
- return () => {
- model.state.removeOnChangedHandler(onStateChange);
- };
- }, [])
-
- const theme = useTheme();
-
- return (
-
-
-
-
-
-
-
-
- ModGUI Test
-
- {pluginUrl ? pluginUrl : "No plugin loaded"}
-
- setPluginDialogOpen(true)} >
- Load
-
-
-
-
-
- {uiPlugin && (
-
- {
- setPluginUrl("");
- setUiPlugin(null);
- setValueHandler(null);
- }} >
-
- {
- setPluginUrl("");
- setUiPlugin(null);
- }}
- hostSite={modGuiHostSite}
- />
-
-
- )}
- {pluginDialogOpen &&
-
{
- setPluginUrl(url as string);
- let uiPlugin = model.getUiPlugin(url);
- setUiPlugin(uiPlugin);
- if (uiPlugin) {
- setValueHandler(new ValueHandler(-1, uiPlugin));
- }
- setPluginDialogOpen(false);
- }}
- onCancel={() => setPluginDialogOpen(false)}
- uri={pluginUrl}
- modGuiOnly={true}
- />
- }
-
- );
-}
-
-export default ModGuiTest;
\ No newline at end of file
diff --git a/vite/src/pipedal/Pedalboard.tsx b/vite/src/pipedal/Pedalboard.tsx
index c18a2cc..a5129ba 100644
--- a/vite/src/pipedal/Pedalboard.tsx
+++ b/vite/src/pipedal/Pedalboard.tsx
@@ -79,6 +79,8 @@ export class PedalboardItem implements Deserializable {
this.lv2State = input.lv2State;
this.lilvPresetUri = input.lilvPresetUri;
this.pathProperties = input.pathProperties;
+ this.useModUi = input.useModUi ?? false;
+
return this;
}
deserialize(input: any): PedalboardItem {
@@ -212,6 +214,7 @@ export class PedalboardItem implements Deserializable {
lv2State: [boolean,any] = [false,{}];
lilvPresetUri: string = "";
pathProperties: {[Name: string]: string} = {};
+ useModUi: boolean = false; // true if this item should use the mod-ui.
};
export class SnapshotValue {
diff --git a/vite/src/pipedal/PiPedalModel.tsx b/vite/src/pipedal/PiPedalModel.tsx
index 70d26ce..0fda9f3 100644
--- a/vite/src/pipedal/PiPedalModel.tsx
+++ b/vite/src/pipedal/PiPedalModel.tsx
@@ -44,7 +44,7 @@ import FilePropertyDirectoryTree from './FilePropertyDirectoryTree';
import AudioFileMetadata from './AudioFileMetadata';
import { pathFileName } from './FileUtils';
import { AlsaSequencerConfiguration, AlsaSequencerPortSelection } from './AlsaSequencer';
-
+import {getDefaultModGuiPreference} from './ModGuiHost';
export enum State {
Loading,
@@ -82,6 +82,24 @@ export enum ReconnectReason {
HotspotChanging
};
+export type PedalboardItemEnabledChangeCallback = (instanceId: number, isEnabled: boolean) => void;
+interface PedalboardItemEnabledChangeItem {
+ handle: number;
+ instanceId: number;
+ currentValue: boolean;
+ onEnabledChanged: PedalboardItemEnabledChangeCallback;
+};
+
+export type PedalboardItemUseModUiChangeCallback = (instanceId: number, useModUi: boolean) => void;
+
+interface PedalboardItemUseModUiChangeItem {
+ handle: number;
+ instanceId: number;
+ currentValue: boolean;
+ onUseModUiChanged: PedalboardItemUseModUiChangeCallback;
+};
+
+
export type ControlValueChangedHandler = (key: string, value: number) => void;
export interface FileEntry {
@@ -146,7 +164,6 @@ export interface VuUpdateInfo {
};
export interface MonitorPortHandle {
-
};
export interface ControlValueChangedHandle {
_ControlValueChangedHandle: number;
@@ -574,10 +591,18 @@ export class PiPedalModel //implements PiPedalModel
return true;
}
+ private updateEnabledItems(pedalboard: Pedalboard)
+ {
+ for (let item of pedalboard.itemsGenerator()) {
+ this.updatePedalboardItemEnabled(item.instanceId, item.isEnabled);
+ this.updatePedalboardItemUseModUi(item.instanceId, item.useModUi);
+ }
+ }
+
private setModelPedalboard(pedalboard: Pedalboard) {
this.pedalboard.set(pedalboard);
this.selectedSnapshot.set(pedalboard.selectedSnapshot);
-
+ this.updateEnabledItems(pedalboard);
}
onSocketMessage(header: PiPedalMessageHeader, body?: any) {
@@ -687,6 +712,13 @@ export class PiPedalModel //implements PiPedalModel
itemEnabledBody.enabled,
false // No server notification.
);
+ } else if (message == "onItemUseModUiChanged") {
+ let itemEnabledBody = body as PedalboardItemEnableBody;
+ this._setPedalboardItemUseModUi(
+ itemEnabledBody.instanceId,
+ itemEnabledBody.enabled,
+ false // No server notification.
+ );
} else if (message === "onPedalboardChanged") {
let pedalChangedBody = body as PedalboardChangedBody;
this.setModelPedalboard(new Pedalboard().deserialize(pedalChangedBody.pedalboard));
@@ -1563,6 +1595,42 @@ export class PiPedalModel //implements PiPedalModel
setPedalboardItemEnabled(instanceId: number, value: boolean): void {
this._setPedalboardItemEnabled(instanceId, value, true);
}
+
+ setPedalboardItemUseModUi(instanceId: number, useModUi: boolean): void {
+ this._setPedalboardItemUseModUi(instanceId, useModUi, true);
+ }
+
+ getPedalboardItemUseModUi(instanceId: number): boolean {
+ if (!this.pedalboard.get().hasItem(instanceId)) return false;
+ let item = this.pedalboard.get().getItem(instanceId);
+ return item.useModUi;
+ }
+ _setPedalboardItemUseModUi(instanceId: number, useModUi: boolean, notifyServer: boolean): void {
+ let pedalboard = this.pedalboard.get();
+ if (pedalboard === undefined) throw new PiPedalStateError("Pedalboard not ready.");
+ let newPedalboard = pedalboard.clone();
+ let item = newPedalboard.getItem(instanceId);
+ let changed = useModUi !== item.useModUi;
+ if (changed) {
+ item.useModUi = useModUi;
+ this.setModelPedalboard(newPedalboard);
+ if (notifyServer) {
+ let body = {
+ clientId: this.clientId,
+ instanceId: instanceId,
+ useModUi: useModUi
+ };
+ this.webSocket?.send("setPedalboardItemUseModUi", body);
+ }
+ }
+ }
+
+
+ getPedalboardItemEnabled(instanceId: number): boolean {
+ if (!this.pedalboard.get().hasItem(instanceId)) return false;
+ let item = this.pedalboard.get().getItem(instanceId);
+ return item.isEnabled;
+ }
private _setPedalboardItemEnabled(instanceId: number, value: boolean, notifyServer: boolean): void {
let pedalboard = this.pedalboard.get();
if (pedalboard === undefined) throw new PiPedalStateError("Pedalboard not ready.");
@@ -1625,6 +1693,7 @@ export class PiPedalModel //implements PiPedalModel
item.lv2State = [false, {}];
item.vstState = "";
item.pathProperties = {};
+ item.useModUi = getDefaultModGuiPreference(selectedUri);
for (let fileProperty of plugin.fileProperties) {
// stringized json for an atom. see AtomConverter.hpp.
// null -> we've never seen a value.
@@ -1845,6 +1914,7 @@ export class PiPedalModel //implements PiPedalModel
}
newPedalboard.setItemEmpty(item);
+
this.setModelPedalboard(newPedalboard);
this.updateServerPedalboard();
return item.instanceId;
@@ -2210,6 +2280,18 @@ export class PiPedalModel //implements PiPedalModel
}
getPatchProperty(instanceId: number, uri: string): Promise {
let result = new Promise((resolve, reject) => {
+ let pedalboard = this.pedalboard.get();
+ if (pedalboard) {
+ let item = pedalboard.getItem(instanceId);
+ if (item) {
+ if (item.pathProperties.hasOwnProperty(uri)) {
+ let value = item.pathProperties[uri];
+ let jsonValue = JSON.parse(value);
+ resolve(jsonValue as Type);
+ }
+
+ }
+ }
if (!this.webSocket) {
reject("Socket closed.");
} else {
@@ -3233,6 +3315,94 @@ export class PiPedalModel //implements PiPedalModel
throw new Error("No connection.");
}
+
+ private pedalboardItemEnabledChangeListeners: PedalboardItemEnabledChangeItem[] = [];
+ private pedalboardItemUseModUiChangeListeners: PedalboardItemUseModUiChangeItem[] = [];
+
+ private updatePedalboardItemEnabled(instanceId: number, enabled: boolean) {
+ for (let listener of this.pedalboardItemEnabledChangeListeners) {
+ if (listener.instanceId === instanceId) {
+ if (listener.currentValue !== enabled) {
+ listener.currentValue = enabled;
+ listener.onEnabledChanged(instanceId, enabled);
+ }
+ }
+ }
+ }
+
+ private updatePedalboardItemUseModUi(instanceId: number, useModUi: boolean) {
+ for (let listener of this.pedalboardItemUseModUiChangeListeners) {
+ if (listener.instanceId === instanceId) {
+ if (listener.currentValue !== useModUi) {
+ listener.currentValue = useModUi;
+ listener.onUseModUiChanged(instanceId, useModUi);
+ }
+ }
+ }
+ }
+
+ addPedalboardItemEnabledChangeListener(
+ instanceId: number,
+ onEnabledChanged: PedalboardItemEnabledChangeCallback
+ ) : ListenHandle{
+ let handle = ++this.nextListenHandle;
+ let currentValue = this.getPedalboardItemEnabled(instanceId);
+
+ let entry: PedalboardItemEnabledChangeItem = {
+ instanceId: instanceId,
+ handle: handle,
+ currentValue: currentValue,
+ onEnabledChanged: onEnabledChanged
+ };
+
+ this.pedalboardItemEnabledChangeListeners.push( entry);
+
+ onEnabledChanged(instanceId, currentValue);
+
+ return { _handle: handle };
+ }
+ addPedalboardItemUseModUiChangeListener(
+ instanceId: number,
+ onUseModUiChanged : PedalboardItemUseModUiChangeCallback
+ ) : ListenHandle{
+
+ let handle = ++this.nextListenHandle;
+ let currentValue = this.getPedalboardItemUseModUi(instanceId);
+
+ let entry: PedalboardItemUseModUiChangeItem = {
+ instanceId: instanceId,
+ handle: handle,
+ currentValue: currentValue,
+ onUseModUiChanged: onUseModUiChanged
+ };
+
+ this.pedalboardItemUseModUiChangeListeners.push( entry);
+
+ onUseModUiChanged(instanceId, currentValue);
+
+ return { _handle: handle };
+ }
+
+ removePedalboardItemEnabledChangeListener(listenHandle: ListenHandle): boolean {
+ for (let i = 0; i < this.pedalboardItemEnabledChangeListeners.length; ++i) {
+ if (this.pedalboardItemEnabledChangeListeners[i].handle === listenHandle._handle) {
+ this.pedalboardItemEnabledChangeListeners.splice(i, 1);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ removePedalboardItemUseModUiChangeListener(listenHandle: ListenHandle): boolean {
+ for (let i = 0; i < this.pedalboardItemUseModUiChangeListeners.length; ++i) {
+ if (this.pedalboardItemUseModUiChangeListeners[i].handle === listenHandle._handle) {
+ this.pedalboardItemUseModUiChangeListeners.splice(i, 1);
+ return true;
+ }
+ }
+ return false;
+ }
+
};
let instance: PiPedalModel | undefined = undefined;
diff --git a/vite/src/pipedal/PluginControlView.tsx b/vite/src/pipedal/PluginControlView.tsx
index 6c3c097..976b9cd 100644
--- a/vite/src/pipedal/PluginControlView.tsx
+++ b/vite/src/pipedal/PluginControlView.tsx
@@ -1,4 +1,4 @@
-// Copyright (c) 2022 Robin Davies
+// Copyright (c) 2025 Robin E. R. Davies
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
@@ -23,7 +23,9 @@ import WithStyles, { withTheme } from './WithStyles';
import { createStyles } from './WithStyles';
import { css } from '@emotion/react';
-import ModGuiHost, { IModGuiHostSite } from './ModGuiHost';
+import AutoZoom from './AutoZoom';
+
+import ModGuiHost from './ModGuiHost';
import { withStyles } from "tss-react/mui";
import { PiPedalModel, PiPedalModelFactory } from './PiPedalModel';
@@ -353,7 +355,9 @@ type PluginControlViewState = {
imeInitialHeight: number;
showFileDialog: boolean,
dialogFileProperty: UiFileProperty,
- dialogFileValue: string
+ dialogFileValue: string,
+ modGuiContentReady: boolean,
+ showModGuiZoomed: boolean,
};
const PluginControlView =
@@ -372,7 +376,9 @@ const PluginControlView =
imeInitialHeight: 0,
showFileDialog: false,
dialogFileProperty: new UiFileProperty(),
- dialogFileValue: ""
+ dialogFileValue: "",
+ modGuiContentReady: false,
+ showModGuiZoomed: false
}
this.onPedalboardChanged = this.onPedalboardChanged.bind(this);
@@ -774,36 +780,64 @@ const PluginControlView =
}
return false;
}
- makeHostSite(): IModGuiHostSite {
- // Yuck. :-( This worked out badly.
- let model = this.model;
- return {
- monitorPort: this.model.monitorPort.bind(model),
- unmonitorPort: this.model.unmonitorPort.bind(model),
- setPedalboardControl: this.model.setPedalboardControl.bind(model),
- monitorPatchProperty: this.model.monitorPatchProperty.bind(model),
- cancelMonitorPatchProperty: this.model.cancelMonitorPatchProperty.bind(model),
- getPatchProperty: this.model.getPatchProperty.bind(model),
- setPatchProperty: this.model.setPatchProperty.bind(model),
- };
- }
+
+ handleModGuiFileProperty(instanceId: number, filePropertyUri: string, selectedFile: string) {
+ let plugin = this.model.getUiPlugin(this.props.item.uri);
+ if (!plugin) {
+ throw (new Error("Plugin not found."));
+ }
+ let fileProperty = plugin.getFilePropertyByUri(filePropertyUri);
+ if (!fileProperty) {
+ throw (new Error("File property not found."));
+ }
+ this.setState({
+ showFileDialog: true,
+ dialogFileProperty: fileProperty,
+ dialogFileValue: selectedFile
+ });
+ }
renderModGui(): ReactNode {
+ const classes = withStyles.getClasses(this.props);
+ void classes;
+
let uiPlugin = this.model.getUiPlugin(this.props.item.uri);
if (!uiPlugin) {
return ();
}
return (
- {
- if (this.props.onSetShowModGui) {
- this.props.onSetShowModGui(this.props.instanceId, false);
+
+
{ this.setState({ showModGuiZoomed: value }); }
}
- }}
- hostSite={this.makeHostSite()}
- />
+ >
+ {
+ if (this.props.onSetShowModGui) {
+ this.props.onSetShowModGui(this.props.instanceId, false);
+ }
+ this.setState({showModGuiZoomed: false})
+ }}
+ handleFileSelect={(instanceId, fileProperty, selectedFile) => {
+ this.handleModGuiFileProperty(
+ instanceId,
+ fileProperty,
+ selectedFile);
+
+ }}
+ onContentReady={(value) => {
+ this.setState({ modGuiContentReady: value });
+ }}
+ />
+
+
+
)
}
@@ -859,22 +893,22 @@ const PluginControlView =
nodes.push(this.midiBindingControl(pedalboardItem));
}
return (
-
-
- {
- nodes
- }
- {/* Extra space to allow scrolling right to the end in lascape especially */}
- {!this.fullScreen() && (
-
- )}
- {
- (!this.state.landscapeGrid) && (!this.fullScreen()) && (
-
- )
- }
-
+
+
+ {
+ nodes
+ }
+ {/* Extra space to allow scrolling right to the end in lascape especially */}
+ {!this.fullScreen() && (
+
+ )}
+ {
+ (!this.state.landscapeGrid) && (!this.fullScreen()) && (
+
+ )
+ }
+
);
@@ -895,7 +929,7 @@ const PluginControlView =
let vuMeterRClass = this.state.landscapeGrid ? classes.vuMeterRLandscape : classes.vuMeterR;
let frameClass = classes.frame;
- if (this.fullScreen()) {
+ if (this.fullScreen() || this.props.showModGui) {
frameClass = classes.noScrollFrame;
}
@@ -920,13 +954,15 @@ const PluginControlView =
instanceId={this.props.instanceId}
selectedFile={this.state.dialogFileValue}
onCancel={() => {
- this.setState({ showFileDialog: false });
+ this.setState({
+ showFileDialog: false
+ });
}}
onApply={(fileProperty, selectedFile) => {
this.model.setPatchProperty(
this.props.instanceId,
fileProperty.patchProperty,
- JsonAtom.Path(selectedFile)
+ JsonAtom._Path(selectedFile).asAny()
)
.then(() => {
@@ -941,7 +977,7 @@ const PluginControlView =
this.model.setPatchProperty(
this.props.instanceId,
fileProperty.patchProperty,
- JsonAtom.Path(selectedFile)
+ JsonAtom._Path(selectedFile).asAny()
)
.then(() => {
diff --git a/vite/src/pipedal/Rect.tsx b/vite/src/pipedal/Rect.tsx
index 096f377..8ef44d1 100644
--- a/vite/src/pipedal/Rect.tsx
+++ b/vite/src/pipedal/Rect.tsx
@@ -31,7 +31,7 @@ class Rect {
this.x = x; this.y = y; this.width = width; this.height = height;
}
- toString() { return '{' + this.x + "," + this.y + " " + this.width + "," + this.height +"}"; }
+ toString() { return '{' + this.x + "," + this.y + " - " + this.width + "," + this.height +"}"; }
copy(): Rect {
let result = new Rect();
result.x = this.x;
@@ -84,6 +84,12 @@ class Rect {
this.x += xOffset;
this.y += yOffset;
}
+ equals(other: Rect): boolean {
+ return this.x === other.x &&
+ this.y === other.y &&
+ this.width === other.width &&
+ this.height === other.height;
+ }
}
export default Rect;
\ No newline at end of file
diff --git a/vite/src/pipedal/ScratchClass.tsx b/vite/src/pipedal/ScratchClass.tsx
index c6655f8..fbe6a6e 100644
--- a/vite/src/pipedal/ScratchClass.tsx
+++ b/vite/src/pipedal/ScratchClass.tsx
@@ -1,4 +1,4 @@
-// Copyright (c) 2022 Robin Davies
+// Copyright (c) 2025 Robin E. R. Davies
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
diff --git a/vite/src/pipedal/ToobCabSimView.tsx b/vite/src/pipedal/ToobCabSimView.tsx
index caa0e3e..74fc3b4 100644
--- a/vite/src/pipedal/ToobCabSimView.tsx
+++ b/vite/src/pipedal/ToobCabSimView.tsx
@@ -77,6 +77,9 @@ const ToobCabSimView =
item={this.props.item}
customization={this}
customizationId={this.customizationId}
+ showModGui={false}
+ onSetShowModGui= {(instanceId: number, showModGui: boolean) => {}}
+
/>);
}
},
diff --git a/vite/src/pipedal/ToobInputStageView.tsx b/vite/src/pipedal/ToobInputStageView.tsx
index dd37f4c..91321f7 100644
--- a/vite/src/pipedal/ToobInputStageView.tsx
+++ b/vite/src/pipedal/ToobInputStageView.tsx
@@ -21,14 +21,14 @@ import React from 'react';
import { Theme } from '@mui/material/styles';
import WithStyles from './WithStyles';
-import {createStyles} from './WithStyles';
+import { createStyles } from './WithStyles';
import { withStyles } from "tss-react/mui";
import IControlViewFactory from './IControlViewFactory';
import { PiPedalModelFactory, PiPedalModel } from "./PiPedalModel";
import { PedalboardItem } from './Pedalboard';
-import PluginControlView, { ControlGroup,ControlViewCustomization } from './PluginControlView';
+import PluginControlView, { ControlGroup, ControlViewCustomization } from './PluginControlView';
//import ToobFrequencyResponseView from './ToobFrequencyResponseView';
@@ -47,12 +47,11 @@ interface ToobInputStageState {
const ToobInputStageView =
withStyles(
- class extends React.Component
- implements ControlViewCustomization
- {
+ class extends React.Component
+ implements ControlViewCustomization {
model: PiPedalModel;
- customizationId: number = 1;
+ customizationId: number = 1;
constructor(props: ToobInputStageProps) {
super(props);
@@ -64,8 +63,7 @@ const ToobInputStageView =
return false;
}
- modifyControls(controls: (React.ReactNode| ControlGroup)[]): (React.ReactNode| ControlGroup)[]
- {
+ modifyControls(controls: (React.ReactNode | ControlGroup)[]): (React.ReactNode | ControlGroup)[] {
return controls;
// let group = controls[1] as ControlGroup;
// group.controls.splice(0,0,
@@ -79,6 +77,9 @@ const ToobInputStageView =
item={this.props.item}
customization={this}
customizationId={this.customizationId}
+ showModGui={false}
+ onSetShowModGui={(instanceId: number, showModGui: boolean) => { }}
+
/>);
}
},
diff --git a/vite/src/pipedal/ToobMLView.tsx b/vite/src/pipedal/ToobMLView.tsx
index d4dd702..378b07f 100644
--- a/vite/src/pipedal/ToobMLView.tsx
+++ b/vite/src/pipedal/ToobMLView.tsx
@@ -21,7 +21,7 @@ import React from 'react';
import { Theme } from '@mui/material/styles';
import WithStyles from './WithStyles';
-import {createStyles} from './WithStyles';
+import { createStyles } from './WithStyles';
import { withStyles } from "tss-react/mui";
@@ -48,7 +48,7 @@ const ToobMLView =
class extends React.Component
implements ControlViewCustomization {
model: PiPedalModel;
- gainRef: React.RefObject;
+ gainRef: React.RefObject;
customizationId: number = 1;
@@ -119,19 +119,17 @@ const ToobMLView =
// }
let controlIndex: number = -1;
let controlValues = this.props.item.controlValues
- for (let i:number = 0; i < controlValues.length; ++i)
- {
+ for (let i: number = 0; i < controlValues.length; ++i) {
let ctl: any = controls[i];
- let key: any = ctl?.props?.uiControl?.symbol??"";
-
- if (key === "gain")
- {
+ let key: any = ctl?.props?.uiControl?.symbol ?? "";
+
+ if (key === "gain") {
controlIndex = i;
break;
}
}
- if (controlIndex !== -1 ) {
+ if (controlIndex !== -1) {
let gainControl: React.ReactElement = controls[controlIndex] as React.ReactElement;
controls[controlIndex] = ( {gainControl}
);
@@ -144,6 +142,9 @@ const ToobMLView =
item={this.props.item}
customization={this}
customizationId={this.customizationId}
+ showModGui={false}
+ onSetShowModGui={(instanceId: number, showModGui: boolean) => { }}
+
/>);
}
},
diff --git a/vite/src/pipedal/ToobPlayerControl.tsx b/vite/src/pipedal/ToobPlayerControl.tsx
index ac80320..b36ab68 100644
--- a/vite/src/pipedal/ToobPlayerControl.tsx
+++ b/vite/src/pipedal/ToobPlayerControl.tsx
@@ -525,7 +525,7 @@ export default function ToobPlayerControl(
function onNextTrack() {
model.getNextAudioFile(audioFile)
.then((file) => {
- let json = JsonAtom.Path(file);
+ let json = JsonAtom._Path(file).asAny();
model.setPatchProperty(
props.instanceId,
AUDIO_FILE_PROPERTY_URI,
@@ -538,7 +538,7 @@ export default function ToobPlayerControl(
function onPreviousTrack() {
model.getPreviousAudioFile(audioFile)
.then((file) => {
- let json = JsonAtom.Path(file);
+ let json = JsonAtom._Path(file).asAny();
model.setPatchProperty(
props.instanceId,
AUDIO_FILE_PROPERTY_URI,
@@ -873,7 +873,7 @@ export default function ToobPlayerControl(
model.setPatchProperty(
props.instanceId,
AUDIO_FILE_PROPERTY_URI,
- JsonAtom.Path(selectedFile)
+ JsonAtom._Path(selectedFile).asAny()
)
.then(() => {
@@ -888,7 +888,7 @@ export default function ToobPlayerControl(
model.setPatchProperty(
props.instanceId,
fileProperty.patchProperty,
- JsonAtom.Path(selectedFile)
+ JsonAtom._Path(selectedFile).asAny()
)
.then(() => {
diff --git a/vite/src/pipedal/ToobPlayerView.tsx b/vite/src/pipedal/ToobPlayerView.tsx
index 1f40908..751620c 100644
--- a/vite/src/pipedal/ToobPlayerView.tsx
+++ b/vite/src/pipedal/ToobPlayerView.tsx
@@ -110,14 +110,14 @@ const ToobPlayerView =
for (let mixControl of mixPanel.controls) {
extraControls.push(
(
-
+
{mixControl}
));
}
let panel = (
-
+
);
let result: (React.ReactNode | ControlGroup)[] = [];
@@ -133,6 +133,9 @@ const ToobPlayerView =
item={this.props.item}
customization={this}
customizationId={this.customizationId}
+ showModGui={false}
+ onSetShowModGui={(instanceId: number, showModGui: boolean) => { }}
+
/>
);
}
@@ -146,7 +149,7 @@ class ToobPlayerViewFactory implements IControlViewFactory {
uri: string = "http://two-play.com/plugins/toob-player";
Create(model: PiPedalModel, pedalboardItem: PedalboardItem): React.ReactNode {
- return (
);
+ return (
);
}
diff --git a/vite/src/pipedal/ToobPowerStage2View.tsx b/vite/src/pipedal/ToobPowerStage2View.tsx
index 3d1e8b2..664747d 100644
--- a/vite/src/pipedal/ToobPowerStage2View.tsx
+++ b/vite/src/pipedal/ToobPowerStage2View.tsx
@@ -179,6 +179,8 @@ const ToobPowerstage2View =
item={this.props.item}
customization={this}
customizationId={this.customizationId}
+ showModGui={false}
+ onSetShowModGui= {(instanceId: number, showModGui: boolean) => {}}
/>);
}
},
diff --git a/vite/src/pipedal/ToobSpectrumAnalyzerView.tsx b/vite/src/pipedal/ToobSpectrumAnalyzerView.tsx
index 103d530..269f958 100644
--- a/vite/src/pipedal/ToobSpectrumAnalyzerView.tsx
+++ b/vite/src/pipedal/ToobSpectrumAnalyzerView.tsx
@@ -21,14 +21,14 @@ import React from 'react';
import { Theme } from '@mui/material/styles';
import WithStyles from './WithStyles';
-import {createStyles} from './WithStyles';
+import { createStyles } from './WithStyles';
import { withStyles } from "tss-react/mui";
import IControlViewFactory from './IControlViewFactory';
import { PiPedalModelFactory, PiPedalModel } from "./PiPedalModel";
import { PedalboardItem } from './Pedalboard';
-import PluginControlView, { ControlGroup,ControlViewCustomization } from './PluginControlView';
+import PluginControlView, { ControlGroup, ControlViewCustomization } from './PluginControlView';
import ToobSpectrumResponseView from './ToobSpectrumResponseView';
@@ -48,12 +48,11 @@ interface ToobSpectrumAnalyzerState {
const ToobSpectrumAnalyzerView =
withStyles(
- class extends React.Component
- implements ControlViewCustomization
- {
+ class extends React.Component
+ implements ControlViewCustomization {
model: PiPedalModel;
- customizationId: number = 1;
+ customizationId: number = 1;
constructor(props: ToobSpectrumAnalyzerProps) {
super(props);
@@ -65,11 +64,10 @@ const ToobSpectrumAnalyzerView =
return false;
}
- modifyControls(controls: (React.ReactNode| ControlGroup)[]): (React.ReactNode| ControlGroup)[]
- {
- controls.splice(0,0,
- ( )
- );
+ modifyControls(controls: (React.ReactNode | ControlGroup)[]): (React.ReactNode | ControlGroup)[] {
+ controls.splice(0, 0,
+ ()
+ );
return controls;
}
render() {
@@ -78,6 +76,9 @@ const ToobSpectrumAnalyzerView =
item={this.props.item}
customization={this}
customizationId={this.customizationId}
+ showModGui={false}
+ onSetShowModGui={(instanceId: number, showModGui: boolean) => { }}
+
/>);
}
},
diff --git a/vite/src/pipedal/ToobToneStackView.tsx b/vite/src/pipedal/ToobToneStackView.tsx
index 055177a..bf7dfd7 100644
--- a/vite/src/pipedal/ToobToneStackView.tsx
+++ b/vite/src/pipedal/ToobToneStackView.tsx
@@ -21,14 +21,14 @@ import React from 'react';
import { Theme } from '@mui/material/styles';
import WithStyles from './WithStyles';
-import {createStyles} from './WithStyles';
+import { createStyles } from './WithStyles';
import { withStyles } from "tss-react/mui";
import IControlViewFactory from './IControlViewFactory';
-import { PiPedalModelFactory, PiPedalModel,ControlValueChangedHandle } from "./PiPedalModel";
+import { PiPedalModelFactory, PiPedalModel, ControlValueChangedHandle } from "./PiPedalModel";
import { PedalboardItem } from './Pedalboard';
-import PluginControlView, { ControlGroup,ControlViewCustomization } from './PluginControlView';
+import PluginControlView, { ControlGroup, ControlViewCustomization } from './PluginControlView';
import ToobFrequencyResponseView from './ToobFrequencyResponseView';
@@ -47,12 +47,11 @@ interface ToobToneStackState {
const ToobToneStackView =
withStyles(
- class extends React.Component
- implements ControlViewCustomization
- {
+ class extends React.Component
+ implements ControlViewCustomization {
model: PiPedalModel;
- customizationId: number = 1;
+ customizationId: number = 1;
constructor(props: ToobToneStackProps) {
super(props);
@@ -61,27 +60,24 @@ const ToobToneStackView =
isBaxandall: this.IsBaxandall()
}
}
- IsBaxandall() : boolean {
+ IsBaxandall(): boolean {
return this.props.item.getControl("ampmodel").value === 2.0;
}
controlValueChangedHandle?: ControlValueChangedHandle;
- componentDidMount()
- {
+ componentDidMount() {
this.controlValueChangedHandle = this.model.addControlValueChangeListener(
this.props.instanceId,
- (key,value) => {
- if (key === "ampmodel")
- {
- this.setState({isBaxandall: value === 2.0});
+ (key, value) => {
+ if (key === "ampmodel") {
+ this.setState({ isBaxandall: value === 2.0 });
}
}
);
}
componentWillUnmount() {
- if (this.controlValueChangedHandle)
- {
+ if (this.controlValueChangedHandle) {
this.model.removeControlValueChangeListener(this.controlValueChangedHandle);
this.controlValueChangedHandle = undefined;
}
@@ -90,18 +86,16 @@ const ToobToneStackView =
return false;
}
- modifyControls(controls: (React.ReactNode| ControlGroup)[]): (React.ReactNode| ControlGroup)[]
- {
- if (this.state.isBaxandall)
- {
- controls.splice(0,0,
- ( )
- );
+ modifyControls(controls: (React.ReactNode | ControlGroup)[]): (React.ReactNode | ControlGroup)[] {
+ if (this.state.isBaxandall) {
+ controls.splice(0, 0,
+ ()
+ );
} else {
- controls.splice(0,0,
- ( )
- );
+ controls.splice(0, 0,
+ ()
+ );
}
return controls;
}
@@ -111,6 +105,9 @@ const ToobToneStackView =
item={this.props.item}
customization={this}
customizationId={this.customizationId}
+ showModGui={false}
+ onSetShowModGui={(instanceId: number, showModGui: boolean) => { }}
+
/>);
}
},