Allow .zip bundle uploads for all File plugin controls.
This commit is contained in:
@@ -1,14 +1,13 @@
|
|||||||
# Release Notes
|
# Release Notes
|
||||||
## PiPedal 1.2.41
|
## PiPedal 1.2.41 Release
|
||||||
Version 1.2 is officially released.
|
|
||||||
|
|
||||||
This version includes the following new features:
|
This version includes the following new features:
|
||||||
|
|
||||||
- Supports Raspberry Pi 5.
|
- Supports Raspberry Pi 5.
|
||||||
- Supports Rasberry Pi OS Bookworm.
|
- Supports Rasberry Pi OS Bookworm.
|
||||||
- TooB ML allows uploading of models. See below for further details.
|
- TooB ML allows uploading of models. See below for further details.
|
||||||
- TooB ML allows uploading of model collections contained in .zip files.
|
|
||||||
- TooBML support for large models (e.g. GuitarML Proteus models)
|
- TooBML support for large models (e.g. GuitarML Proteus models)
|
||||||
|
- Upload .zip file bundles to all File plugin controls.
|
||||||
- Uploads can be organized into sub-directories.
|
- Uploads can be organized into sub-directories.
|
||||||
- Various minor improvements to TooB plugin user interfaces.
|
- Various minor improvements to TooB plugin user interfaces.
|
||||||
|
|
||||||
|
|||||||
@@ -370,7 +370,7 @@ export default withStyles(styles, { withTheme: true })(
|
|||||||
<Link underline="hover"
|
<Link underline="hover"
|
||||||
color="inherit"
|
color="inherit"
|
||||||
key="1" onClick={() => { this.navigate(""); }}
|
key="1" onClick={() => { this.navigate(""); }}
|
||||||
sx={{ display: 'flex', alignItems: 'center' }}
|
sx={{ display: 'flex', alignItems: 'center',cursor: "default" }}
|
||||||
>
|
>
|
||||||
<HomeIcon sx={{ mr: 0.6 }} fontSize="inherit" />
|
<HomeIcon sx={{ mr: 0.6 }} fontSize="inherit" />
|
||||||
Home
|
Home
|
||||||
@@ -383,7 +383,7 @@ export default withStyles(styles, { withTheme: true })(
|
|||||||
target = pathConcat(target, directories[i]);
|
target = pathConcat(target, directories[i]);
|
||||||
let myTarget = target;
|
let myTarget = target;
|
||||||
breadcrumbs.push((
|
breadcrumbs.push((
|
||||||
<Link underline="hover" key={(i + 1).toString()}
|
<Link underline="hover" key={(i + 1).toString()} style={{cursor: "default"}}
|
||||||
color="inherit" onClick={() => { this.navigate(myTarget) }}>
|
color="inherit" onClick={() => { this.navigate(myTarget) }}>
|
||||||
{directories[i]}
|
{directories[i]}
|
||||||
</Link>
|
</Link>
|
||||||
@@ -392,7 +392,9 @@ export default withStyles(styles, { withTheme: true })(
|
|||||||
{
|
{
|
||||||
let lastdirectory = directories[directories.length - 1];
|
let lastdirectory = directories[directories.length - 1];
|
||||||
breadcrumbs.push((
|
breadcrumbs.push((
|
||||||
<Typography noWrap key={directories.length.toString()} color="text.secondary"> {lastdirectory}</Typography>
|
<Typography noWrap key={directories.length.toString()}
|
||||||
|
style={{cursor: "default"}}
|
||||||
|
color="text.secondary"> {lastdirectory}</Typography>
|
||||||
));
|
));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+149
-197
@@ -54,8 +54,7 @@ export class Port implements Deserializable<Port> {
|
|||||||
|
|
||||||
static deserialize_array(input: any): Port[] {
|
static deserialize_array(input: any): Port[] {
|
||||||
let result: Port[] = [];
|
let result: Port[] = [];
|
||||||
for (let i = 0; i < input.length; ++i)
|
for (let i = 0; i < input.length; ++i) {
|
||||||
{
|
|
||||||
result[i] = new Port().deserialize(input[i]);
|
result[i] = new Port().deserialize(input[i]);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@@ -91,10 +90,9 @@ export class PortGroup {
|
|||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
static deserialize_array(input: any) : PortGroup[] {
|
static deserialize_array(input: any): PortGroup[] {
|
||||||
let result: PortGroup[] = [];
|
let result: PortGroup[] = [];
|
||||||
for (let i = 0; i < input.length; ++i)
|
for (let i = 0; i < input.length; ++i) {
|
||||||
{
|
|
||||||
result.push(new PortGroup().deserialize(input[i]));
|
result.push(new PortGroup().deserialize(input[i]));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@@ -114,87 +112,88 @@ export class UiFileType {
|
|||||||
this.mimeType = input.mimeType;
|
this.mimeType = input.mimeType;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
static deserialize_array(input: any): UiFileType[]
|
static deserialize_array(input: any): UiFileType[] {
|
||||||
{
|
|
||||||
let result: UiFileType[] = [];
|
let result: UiFileType[] = [];
|
||||||
for (let i = 0; i < input.length; ++i)
|
for (let i = 0; i < input.length; ++i) {
|
||||||
{
|
|
||||||
result[i] = new UiFileType().deserialize(input[i]);
|
result[i] = new UiFileType().deserialize(input[i]);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IsAndroid() : boolean
|
private static IsAndroid(): boolean {
|
||||||
{
|
|
||||||
return /Android/i.test(navigator.userAgent);
|
return /Android/i.test(navigator.userAgent);
|
||||||
}
|
}
|
||||||
static MergeMimeTypes(fileTypes: UiFileType[]): string
|
static MergeMimeTypes(fileTypes: UiFileType[]): string {
|
||||||
{
|
|
||||||
if (fileTypes.length === 0) {
|
if (fileTypes.length === 0) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
let result = fileTypes[0].mimeType;
|
if (this.IsAndroid()) {
|
||||||
for (let i = 1; i < fileTypes.length; ++i)
|
return ""; // allow selection of .zip files, plus whatever. We'll catch it later.
|
||||||
{
|
|
||||||
let fileType = fileTypes[i];
|
|
||||||
if (fileType.mimeType !== result)
|
|
||||||
{
|
|
||||||
if (result.startsWith("audio/") && fileType.mimeType.startsWith("audio/"))
|
|
||||||
{
|
|
||||||
result = "audio/*";
|
|
||||||
} else if (result.startsWith("video/") && fileType.mimeType.startsWith("video/"))
|
|
||||||
{
|
|
||||||
result = "video/*";
|
|
||||||
} else if (result.startsWith("text/") && fileType.mimeType.startsWith("text/"))
|
|
||||||
{
|
|
||||||
result = "text/*";
|
|
||||||
} else {
|
|
||||||
result = "application/octet-stream";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (this.IsAndroid())
|
|
||||||
{
|
|
||||||
if (result.startsWith("audio/")) result = "audio/*";
|
|
||||||
if (result.startsWith("video/")) result = "video/*";
|
|
||||||
if (result.startsWith("text/")) result = "text/*";
|
|
||||||
} else {
|
} else {
|
||||||
// chrome desktop thinks "application/octet-stream" is .exe, .com, or .bat.
|
// chrome desktop thinks "application/octet-stream" is .exe, .com, or .bat.
|
||||||
// Feed it file extensions isntead.
|
// Feed it file extensions isntead.
|
||||||
if (result === "application/octet-stream")
|
let result = "";
|
||||||
|
for (let i = 0; i < fileTypes.length; ++i) {
|
||||||
|
let fileType = fileTypes[i];
|
||||||
|
if (fileType.fileExtension !== "") {
|
||||||
|
if (result.length !== 0) // prefer file extensions.
|
||||||
{
|
{
|
||||||
result = "";
|
result += ",";
|
||||||
for (let i = 0; i < fileTypes.length; ++i)
|
result += fileType.fileExtension;
|
||||||
{
|
|
||||||
if (i !== 0)
|
|
||||||
{
|
|
||||||
result += ',';
|
|
||||||
}
|
}
|
||||||
result += fileTypes[i].fileExtension;
|
} else {
|
||||||
|
if (fileType.mimeType !== result) {
|
||||||
|
let t = "";
|
||||||
|
if (result.startsWith("audio/") && fileType.mimeType.startsWith("audio/")) {
|
||||||
|
t = "audio/*";
|
||||||
|
} else if (result.startsWith("video/") && fileType.mimeType.startsWith("video/")) {
|
||||||
|
t = "video/*";
|
||||||
|
} else if (result.startsWith("text/") && fileType.mimeType.startsWith("text/")) {
|
||||||
|
t = "text/*";
|
||||||
}
|
}
|
||||||
|
if (t.length !== 0) {
|
||||||
|
if (result.length !== 0) {
|
||||||
|
result += ",";
|
||||||
|
}
|
||||||
|
result += t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let hasZip = false;
|
||||||
|
let types = result.split(",");
|
||||||
|
for (let thisType of types) {
|
||||||
|
if (thisType === ".zip") {
|
||||||
|
hasZip = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add .zip files
|
||||||
|
if (!hasZip) {
|
||||||
|
if (result.length !== 0) {
|
||||||
|
result += ",.zip";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
name: string = "";
|
name: string = "";
|
||||||
fileExtension: string = "";
|
fileExtension: string = "";
|
||||||
mimeType: string = "";
|
mimeType: string = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
export class UiPropertyNotification {
|
export class UiPropertyNotification {
|
||||||
deserialize(input: any): UiPropertyNotification
|
deserialize(input: any): UiPropertyNotification {
|
||||||
{
|
|
||||||
this.portIndex = input.portIndex;
|
this.portIndex = input.portIndex;
|
||||||
this.symbol = input.symbol;
|
this.symbol = input.symbol;
|
||||||
this.plugin = input.plugin;
|
this.plugin = input.plugin;
|
||||||
this.protocol = input.protocol;
|
this.protocol = input.protocol;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
static deserialize_array(input: any): UiPropertyNotification[]
|
static deserialize_array(input: any): UiPropertyNotification[] {
|
||||||
{
|
|
||||||
let result: UiPropertyNotification[] = [];
|
let result: UiPropertyNotification[] = [];
|
||||||
for (let i = 0; i < input.length; ++i)
|
for (let i = 0; i < input.length; ++i) {
|
||||||
{
|
|
||||||
result[i] = new UiPropertyNotification().deserialize(input[i]);
|
result[i] = new UiPropertyNotification().deserialize(input[i]);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@@ -207,8 +206,7 @@ export class UiPropertyNotification {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export class UiFrequencyPlot {
|
export class UiFrequencyPlot {
|
||||||
deserialize(input: any): UiFrequencyPlot
|
deserialize(input: any): UiFrequencyPlot {
|
||||||
{
|
|
||||||
this.patchProperty = input.patchProperty;
|
this.patchProperty = input.patchProperty;
|
||||||
this.index = input.index;
|
this.index = input.index;
|
||||||
this.portGroup = input.portGroup;
|
this.portGroup = input.portGroup;
|
||||||
@@ -220,11 +218,9 @@ export class UiFrequencyPlot {
|
|||||||
this.width = input.width;
|
this.width = input.width;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
static deserialize_array(input: any): UiFrequencyPlot[]
|
static deserialize_array(input: any): UiFrequencyPlot[] {
|
||||||
{
|
|
||||||
let result: UiFrequencyPlot[] = [];
|
let result: UiFrequencyPlot[] = [];
|
||||||
for (let i = 0; i < input.length; ++i)
|
for (let i = 0; i < input.length; ++i) {
|
||||||
{
|
|
||||||
result[i] = new UiFrequencyPlot().deserialize(input[i]);
|
result[i] = new UiFrequencyPlot().deserialize(input[i]);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@@ -242,22 +238,19 @@ export class UiFrequencyPlot {
|
|||||||
|
|
||||||
};
|
};
|
||||||
export class UiFileProperty {
|
export class UiFileProperty {
|
||||||
deserialize(input: any): UiFileProperty
|
deserialize(input: any): UiFileProperty {
|
||||||
{
|
|
||||||
this.label = input.label;
|
this.label = input.label;
|
||||||
this.fileTypes = UiFileType.deserialize_array(input.fileTypes);
|
this.fileTypes = UiFileType.deserialize_array(input.fileTypes);
|
||||||
this.patchProperty = input.patchProperty;
|
this.patchProperty = input.patchProperty;
|
||||||
this.directory = input.directory;
|
this.directory = input.directory;
|
||||||
this.index = input.index;
|
this.index = input.index;
|
||||||
this.portGroup = input.portGroup;
|
this.portGroup = input.portGroup;
|
||||||
this.resourceDirectory = input.resourceDirectory??"";
|
this.resourceDirectory = input.resourceDirectory ?? "";
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
static deserialize_array(input: any): UiFileProperty[]
|
static deserialize_array(input: any): UiFileProperty[] {
|
||||||
{
|
|
||||||
let result: UiFileProperty[] = [];
|
let result: UiFileProperty[] = [];
|
||||||
for (let i = 0; i < input.length; ++i)
|
for (let i = 0; i < input.length; ++i) {
|
||||||
{
|
|
||||||
result[i] = new UiFileProperty().deserialize(input[i]);
|
result[i] = new UiFileProperty().deserialize(input[i]);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@@ -265,11 +258,10 @@ export class UiFileProperty {
|
|||||||
|
|
||||||
private static getFileExtension(name: string): string {
|
private static getFileExtension(name: string): string {
|
||||||
let pos = name.lastIndexOf('.');
|
let pos = name.lastIndexOf('.');
|
||||||
let filenamePos = name.lastIndexOf('/') +1;
|
let filenamePos = name.lastIndexOf('/') + 1;
|
||||||
filenamePos = Math.max(name.lastIndexOf('\\')+1);
|
filenamePos = Math.max(name.lastIndexOf('\\') + 1);
|
||||||
filenamePos = Math.max(name.lastIndexOf(':')+1);
|
filenamePos = Math.max(name.lastIndexOf(':') + 1);
|
||||||
if (pos < filenamePos)
|
if (pos < filenamePos) {
|
||||||
{
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -279,19 +271,19 @@ export class UiFileProperty {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
wantsFile(filename: string) : boolean {
|
wantsFile(filename: string): boolean {
|
||||||
if (this.fileTypes.length === 0) {
|
if (this.fileTypes.length === 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
let extension = UiFileProperty.getFileExtension(filename);
|
let extension = UiFileProperty.getFileExtension(filename);
|
||||||
for (let fileType of this.fileTypes)
|
if (extension === ".zip") {
|
||||||
{
|
|
||||||
if (fileType.fileExtension === extension )
|
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (fileType.fileExtension === "*" || fileType.fileExtension === "")
|
for (let fileType of this.fileTypes) {
|
||||||
{
|
if (fileType.fileExtension === extension) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (fileType.fileExtension === "*" || fileType.fileExtension === "") {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -308,12 +300,11 @@ export class UiFileProperty {
|
|||||||
|
|
||||||
};
|
};
|
||||||
export class Lv2Plugin implements Deserializable<Lv2Plugin> {
|
export class Lv2Plugin implements Deserializable<Lv2Plugin> {
|
||||||
deserialize(input: any): Lv2Plugin
|
deserialize(input: any): Lv2Plugin {
|
||||||
{
|
|
||||||
this.uri = input.uri;
|
this.uri = input.uri;
|
||||||
this.name = input.name;
|
this.name = input.name;
|
||||||
this.brand = input.name? input.name: "";
|
this.brand = input.name ? input.name : "";
|
||||||
this.label = input.label? input.label: this.name;
|
this.label = input.label ? input.label : this.name;
|
||||||
this.plugin_class = input.plugin_class;
|
this.plugin_class = input.plugin_class;
|
||||||
this.supported_features = input.supported_features;
|
this.supported_features = input.supported_features;
|
||||||
this.required_features = input.required_features;
|
this.required_features = input.required_features;
|
||||||
@@ -321,23 +312,20 @@ export class Lv2Plugin implements Deserializable<Lv2Plugin> {
|
|||||||
this.author_name = input.author_name;
|
this.author_name = input.author_name;
|
||||||
this.author_homepage = input.author_homepage;
|
this.author_homepage = input.author_homepage;
|
||||||
this.comment = input.comment;
|
this.comment = input.comment;
|
||||||
this.ports= Port.deserialize_array(input.ports);
|
this.ports = Port.deserialize_array(input.ports);
|
||||||
this.port_groups = PortGroup.deserialize_array(input.port_groups);
|
this.port_groups = PortGroup.deserialize_array(input.port_groups);
|
||||||
if (input.fileProperties)
|
if (input.fileProperties) {
|
||||||
{
|
|
||||||
this.fileProperties = UiFileProperty.deserialize_array(input.fileProperties)
|
this.fileProperties = UiFileProperty.deserialize_array(input.fileProperties)
|
||||||
} else {
|
} else {
|
||||||
this.fileProperties = [];
|
this.fileProperties = [];
|
||||||
}
|
}
|
||||||
if (input.frequencyPlots)
|
if (input.frequencyPlots) {
|
||||||
{
|
|
||||||
this.frequencyPlots = UiFrequencyPlot.deserialize_array(input.frequencyPlots)
|
this.frequencyPlots = UiFrequencyPlot.deserialize_array(input.frequencyPlots)
|
||||||
} else {
|
} else {
|
||||||
this.frequencyPlots = [];
|
this.frequencyPlots = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input.uiPortNotifications)
|
if (input.uiPortNotifications) {
|
||||||
{
|
|
||||||
this.uiPortNotifications = UiPropertyNotification.deserialize_array(input.uiPortNotifications);
|
this.uiPortNotifications = UiPropertyNotification.deserialize_array(input.uiPortNotifications);
|
||||||
} else {
|
} else {
|
||||||
this.uiPortNotifications = [];
|
this.uiPortNotifications = [];
|
||||||
@@ -371,11 +359,9 @@ export class ScalePoint implements Deserializable<ScalePoint> {
|
|||||||
this.label = input.label;
|
this.label = input.label;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
static deserialize_array(input: any): ScalePoint[]
|
static deserialize_array(input: any): ScalePoint[] {
|
||||||
{
|
|
||||||
let result: ScalePoint[] = [];
|
let result: ScalePoint[] = [];
|
||||||
for (let i = 0; i < input.length; ++i)
|
for (let i = 0; i < input.length; ++i) {
|
||||||
{
|
|
||||||
result[i] = new ScalePoint().deserialize(input[i]);
|
result[i] = new ScalePoint().deserialize(input[i]);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@@ -386,8 +372,8 @@ export class ScalePoint implements Deserializable<ScalePoint> {
|
|||||||
|
|
||||||
export enum PluginType {
|
export enum PluginType {
|
||||||
// Reserved types used in pedalboards.
|
// Reserved types used in pedalboards.
|
||||||
None="",
|
None = "",
|
||||||
InvalidPlugin= "InvalidPlugin",
|
InvalidPlugin = "InvalidPlugin",
|
||||||
|
|
||||||
Plugin = "Plugin",
|
Plugin = "Plugin",
|
||||||
AllpassPlugin = "AllpassPlugin",
|
AllpassPlugin = "AllpassPlugin",
|
||||||
@@ -458,8 +444,7 @@ export enum ControlType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class UiControl implements Deserializable<UiControl> {
|
export class UiControl implements Deserializable<UiControl> {
|
||||||
deserialize(input: any): UiControl
|
deserialize(input: any): UiControl {
|
||||||
{
|
|
||||||
this.symbol = input.symbol;
|
this.symbol = input.symbol;
|
||||||
this.name = input.name;
|
this.name = input.name;
|
||||||
this.index = input.index;
|
this.index = input.index;
|
||||||
@@ -480,27 +465,23 @@ export class UiControl implements Deserializable<UiControl> {
|
|||||||
this.units = input.units as Units;
|
this.units = input.units as Units;
|
||||||
|
|
||||||
this.comment = input.comment ?? "";
|
this.comment = input.comment ?? "";
|
||||||
this.is_bypass = input.is_bypass ? true: false;
|
this.is_bypass = input.is_bypass ? true : false;
|
||||||
this.is_program_controller = input.is_program_controller? true: false;
|
this.is_program_controller = input.is_program_controller ? true : false;
|
||||||
this.custom_units = input.custom_units ?? "";
|
this.custom_units = input.custom_units ?? "";
|
||||||
this.connection_optional = input.connection_optional ? true: false;
|
this.connection_optional = input.connection_optional ? true : false;
|
||||||
|
|
||||||
|
|
||||||
if (this.is_bypass)
|
if (this.is_bypass) {
|
||||||
{
|
|
||||||
this.not_on_gui = true;
|
this.not_on_gui = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.controlType = ControlType.Dial;
|
this.controlType = ControlType.Dial;
|
||||||
|
|
||||||
if (!this.is_input)
|
if (!this.is_input) {
|
||||||
{
|
if (this.units === Units.midiNote) {
|
||||||
if (this.units === Units.midiNote)
|
|
||||||
{
|
|
||||||
this.controlType = ControlType.Tuner;
|
this.controlType = ControlType.Tuner;
|
||||||
|
|
||||||
} else if (this.units === Units.db)
|
} else if (this.units === Units.db) {
|
||||||
{
|
|
||||||
this.controlType = ControlType.DbVu;
|
this.controlType = ControlType.DbVu;
|
||||||
} else if (this.enumeration_property) {
|
} else if (this.enumeration_property) {
|
||||||
this.controlType = ControlType.OutputSelect;
|
this.controlType = ControlType.OutputSelect;
|
||||||
@@ -508,45 +489,36 @@ export class UiControl implements Deserializable<UiControl> {
|
|||||||
this.controlType = ControlType.Vu;
|
this.controlType = ControlType.Vu;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.isValidEnumeration())
|
if (this.isValidEnumeration()) {
|
||||||
{
|
|
||||||
this.controlType = ControlType.Select;
|
this.controlType = ControlType.Select;
|
||||||
if (this.scale_points.length === 2)
|
if (this.scale_points.length === 2) {
|
||||||
{
|
|
||||||
this.controlType = ControlType.ABSwitch;
|
this.controlType = ControlType.ABSwitch;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (this.toggled_property || (this.integer_property && this.min_value === 0 && this.max_value === 1))
|
if (this.toggled_property || (this.integer_property && this.min_value === 0 && this.max_value === 1)) {
|
||||||
{
|
|
||||||
this.controlType = ControlType.OnOffSwitch;
|
this.controlType = ControlType.OnOffSwitch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
applyProperties(properties: Partial<UiControl>): UiControl
|
applyProperties(properties: Partial<UiControl>): UiControl {
|
||||||
{
|
return { ...this, ...properties };
|
||||||
return {...this,...properties};
|
|
||||||
}
|
}
|
||||||
private hasScalePoint(value: number): boolean {
|
private hasScalePoint(value: number): boolean {
|
||||||
for (let scale_point of this.scale_points)
|
for (let scale_point of this.scale_points) {
|
||||||
{
|
|
||||||
if (scale_point.value === value) return true;
|
if (scale_point.value === value) return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
private isValidEnumeration() : boolean {
|
private isValidEnumeration(): boolean {
|
||||||
if (this.enumeration_property) return true;
|
if (this.enumeration_property) return true;
|
||||||
if (this.toggled_property && this.min_value === 0 && this.max_value === 1)
|
if (this.toggled_property && this.min_value === 0 && this.max_value === 1) {
|
||||||
{
|
if (this.hasScalePoint(this.min_value) && this.hasScalePoint(this.max_value)) {
|
||||||
if (this.hasScalePoint(this.min_value) && this.hasScalePoint(this.max_value))
|
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.integer_property && this.min_value === 0 && this.max_value === 1)
|
if (this.integer_property && this.min_value === 0 && this.max_value === 1) {
|
||||||
{
|
if (this.hasScalePoint(this.min_value) && this.hasScalePoint(this.max_value)) {
|
||||||
if (this.hasScalePoint(this.min_value) && this.hasScalePoint(this.max_value))
|
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -557,8 +529,7 @@ export class UiControl implements Deserializable<UiControl> {
|
|||||||
|
|
||||||
static deserialize_array(input: any): UiControl[] {
|
static deserialize_array(input: any): UiControl[] {
|
||||||
let result: UiControl[] = [];
|
let result: UiControl[] = [];
|
||||||
for (let i = 0; i < input.length; ++i)
|
for (let i = 0; i < input.length; ++i) {
|
||||||
{
|
|
||||||
result[i] = new UiControl().deserialize(input[i]);
|
result[i] = new UiControl().deserialize(input[i]);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@@ -569,11 +540,11 @@ export class UiControl implements Deserializable<UiControl> {
|
|||||||
is_input: boolean = true;
|
is_input: boolean = true;
|
||||||
min_value: number = 0;
|
min_value: number = 0;
|
||||||
max_value: number = 1;
|
max_value: number = 1;
|
||||||
default_value:number = 0.5;
|
default_value: number = 0.5;
|
||||||
is_logarithmic: boolean = false;
|
is_logarithmic: boolean = false;
|
||||||
display_priority: number = -1;
|
display_priority: number = -1;
|
||||||
range_steps: number = 0;
|
range_steps: number = 0;
|
||||||
integer_property:boolean = false;
|
integer_property: boolean = false;
|
||||||
enumeration_property: boolean = false;
|
enumeration_property: boolean = false;
|
||||||
trigger: boolean = false;
|
trigger: boolean = false;
|
||||||
not_on_gui: boolean = false;
|
not_on_gui: boolean = false;
|
||||||
@@ -589,16 +560,13 @@ export class UiControl implements Deserializable<UiControl> {
|
|||||||
|
|
||||||
|
|
||||||
// Return the value of the closest scale_point.
|
// Return the value of the closest scale_point.
|
||||||
clampSelectValue(value: number): number{
|
clampSelectValue(value: number): number {
|
||||||
if (this.scale_points.length !== 0)
|
if (this.scale_points.length !== 0) {
|
||||||
{
|
|
||||||
let minError = 1.0E100;
|
let minError = 1.0E100;
|
||||||
let bestValue = value;
|
let bestValue = value;
|
||||||
for (let i = 0; i < this.scale_points.length; ++i)
|
for (let i = 0; i < this.scale_points.length; ++i) {
|
||||||
{
|
let error = Math.abs(this.scale_points[i].value - value);
|
||||||
let error = Math.abs(this.scale_points[i].value-value);
|
if (error < minError) {
|
||||||
if (error < minError)
|
|
||||||
{
|
|
||||||
minError = error;
|
minError = error;
|
||||||
bestValue = this.scale_points[i].value;
|
bestValue = this.scale_points[i].value;
|
||||||
}
|
}
|
||||||
@@ -609,20 +577,20 @@ export class UiControl implements Deserializable<UiControl> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
isHidden() : boolean {
|
isHidden(): boolean {
|
||||||
return this.not_on_gui || (this.connection_optional && !this.is_input);
|
return this.not_on_gui || (this.connection_optional && !this.is_input);
|
||||||
}
|
}
|
||||||
isOnOffSwitch() : boolean {
|
isOnOffSwitch(): boolean {
|
||||||
return this.controlType === ControlType.OnOffSwitch;
|
return this.controlType === ControlType.OnOffSwitch;
|
||||||
}
|
}
|
||||||
|
|
||||||
isAbToggle(): boolean {
|
isAbToggle(): boolean {
|
||||||
return this.controlType === ControlType.ABSwitch;
|
return this.controlType === ControlType.ABSwitch;
|
||||||
}
|
}
|
||||||
isSelect() : boolean {
|
isSelect(): boolean {
|
||||||
return this.controlType === ControlType.Select;
|
return this.controlType === ControlType.Select;
|
||||||
}
|
}
|
||||||
isOutputSelect() : boolean {
|
isOutputSelect(): boolean {
|
||||||
return !this.is_input && this.controlType === ControlType.OutputSelect;
|
return !this.is_input && this.controlType === ControlType.OutputSelect;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -630,23 +598,23 @@ export class UiControl implements Deserializable<UiControl> {
|
|||||||
isLamp(): boolean {
|
isLamp(): boolean {
|
||||||
return this.toggled_property && this.scale_points.length === 0 && !this.is_input;
|
return this.toggled_property && this.scale_points.length === 0 && !this.is_input;
|
||||||
}
|
}
|
||||||
isDial() : boolean {
|
isDial(): boolean {
|
||||||
return this.controlType === ControlType.Dial;
|
return this.controlType === ControlType.Dial;
|
||||||
}
|
}
|
||||||
|
|
||||||
isTuner() : boolean {
|
isTuner(): boolean {
|
||||||
return this.controlType === ControlType.Tuner;
|
return this.controlType === ControlType.Tuner;
|
||||||
}
|
}
|
||||||
isVu() : boolean {
|
isVu(): boolean {
|
||||||
return this.controlType === ControlType.Vu;
|
return this.controlType === ControlType.Vu;
|
||||||
}
|
}
|
||||||
|
|
||||||
isDbVu() : boolean {
|
isDbVu(): boolean {
|
||||||
return this.controlType === ControlType.DbVu;
|
return this.controlType === ControlType.DbVu;
|
||||||
}
|
}
|
||||||
|
|
||||||
valueToRange(value: number): number {
|
valueToRange(value: number): number {
|
||||||
if (this.toggled_property) return value === 0 ? 0: 1;
|
if (this.toggled_property) return value === 0 ? 0 : 1;
|
||||||
|
|
||||||
if (this.integer_property || this.enumeration_property) {
|
if (this.integer_property || this.enumeration_property) {
|
||||||
value = Math.round(value);
|
value = Math.round(value);
|
||||||
@@ -659,11 +627,11 @@ export class UiControl implements Deserializable<UiControl> {
|
|||||||
return range;
|
return range;
|
||||||
}
|
}
|
||||||
|
|
||||||
rangeToValue(range: number) : number {
|
rangeToValue(range: number): number {
|
||||||
if (range < 0) range = 0;
|
if (range < 0) range = 0;
|
||||||
if (range > 1) range = 1;
|
if (range > 1) range = 1;
|
||||||
|
|
||||||
if (this.toggled_property) return range === 0? 0: 1;
|
if (this.toggled_property) return range === 0 ? 0 : 1;
|
||||||
|
|
||||||
let value = range * (this.max_value - this.min_value) + this.min_value;
|
let value = range * (this.max_value - this.min_value) + this.min_value;
|
||||||
if (this.integer_property || this.enumeration_property) {
|
if (this.integer_property || this.enumeration_property) {
|
||||||
@@ -680,11 +648,9 @@ export class UiControl implements Deserializable<UiControl> {
|
|||||||
value = Math.round(value);
|
value = Math.round(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < this.scale_points.length; ++i)
|
for (let i = 0; i < this.scale_points.length; ++i) {
|
||||||
{
|
|
||||||
let scalePoint = this.scale_points[i];
|
let scalePoint = this.scale_points[i];
|
||||||
if (scalePoint.value === value)
|
if (scalePoint.value === value) {
|
||||||
{
|
|
||||||
return scalePoint.label;
|
return scalePoint.label;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -738,8 +704,7 @@ export class UiControl implements Deserializable<UiControl> {
|
|||||||
}
|
}
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
formatShortValue(value: number): string
|
formatShortValue(value: number): string {
|
||||||
{
|
|
||||||
if (this.enumeration_property) {
|
if (this.enumeration_property) {
|
||||||
for (let i = 0; i < this.scale_points.length; ++i) {
|
for (let i = 0; i < this.scale_points.length; ++i) {
|
||||||
let scale_point = this.scale_points[i];
|
let scale_point = this.scale_points[i];
|
||||||
@@ -766,12 +731,11 @@ export class UiControl implements Deserializable<UiControl> {
|
|||||||
|
|
||||||
|
|
||||||
export class UiPlugin implements Deserializable<UiPlugin> {
|
export class UiPlugin implements Deserializable<UiPlugin> {
|
||||||
deserialize(input: any): UiPlugin
|
deserialize(input: any): UiPlugin {
|
||||||
{
|
|
||||||
this.uri = input.uri;
|
this.uri = input.uri;
|
||||||
this.name = input.name;
|
this.name = input.name;
|
||||||
this.brand = input.brand ? input.brand: "";
|
this.brand = input.brand ? input.brand : "";
|
||||||
this.label = input.label? input.label: this.name;
|
this.label = input.label ? input.label : this.name;
|
||||||
this.plugin_type = input.plugin_type as PluginType;
|
this.plugin_type = input.plugin_type as PluginType;
|
||||||
this.plugin_display_type = input.plugin_display_type;
|
this.plugin_display_type = input.plugin_display_type;
|
||||||
this.author_name = input.author_name;
|
this.author_name = input.author_name;
|
||||||
@@ -783,14 +747,12 @@ export class UiPlugin implements Deserializable<UiPlugin> {
|
|||||||
this.description = input.description;
|
this.description = input.description;
|
||||||
this.controls = UiControl.deserialize_array(input.controls);
|
this.controls = UiControl.deserialize_array(input.controls);
|
||||||
this.port_groups = PortGroup.deserialize_array(input.port_groups);
|
this.port_groups = PortGroup.deserialize_array(input.port_groups);
|
||||||
if (input.fileProperties)
|
if (input.fileProperties) {
|
||||||
{
|
|
||||||
this.fileProperties = UiFileProperty.deserialize_array(input.fileProperties)
|
this.fileProperties = UiFileProperty.deserialize_array(input.fileProperties)
|
||||||
} else {
|
} else {
|
||||||
this.fileProperties = [];
|
this.fileProperties = [];
|
||||||
}
|
}
|
||||||
if (input.frequencyPlots)
|
if (input.frequencyPlots) {
|
||||||
{
|
|
||||||
this.frequencyPlots = UiFrequencyPlot.deserialize_array(input.frequencyPlots)
|
this.frequencyPlots = UiFrequencyPlot.deserialize_array(input.frequencyPlots)
|
||||||
} else {
|
} else {
|
||||||
this.frequencyPlots = [];
|
this.frequencyPlots = [];
|
||||||
@@ -802,8 +764,7 @@ export class UiPlugin implements Deserializable<UiPlugin> {
|
|||||||
}
|
}
|
||||||
static deserialize_array(input: any): UiPlugin[] {
|
static deserialize_array(input: any): UiPlugin[] {
|
||||||
let result: UiPlugin[] = [];
|
let result: UiPlugin[] = [];
|
||||||
for (let i = 0; i < input.length; ++i)
|
for (let i = 0; i < input.length; ++i) {
|
||||||
{
|
|
||||||
result[i] = new UiPlugin().deserialize(input[i]);
|
result[i] = new UiPlugin().deserialize(input[i]);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@@ -814,37 +775,29 @@ export class UiPlugin implements Deserializable<UiPlugin> {
|
|||||||
|
|
||||||
}
|
}
|
||||||
getControl(key: string): UiControl | undefined {
|
getControl(key: string): UiControl | undefined {
|
||||||
for (let i = 0; i < this.controls.length; ++i)
|
for (let i = 0; i < this.controls.length; ++i) {
|
||||||
{
|
|
||||||
let control = this.controls[i];
|
let control = this.controls[i];
|
||||||
if (control.symbol === key)
|
if (control.symbol === key) {
|
||||||
{
|
|
||||||
return control;
|
return control;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
getPortGroupByUri(uri: string) :PortGroup | null
|
getPortGroupByUri(uri: string): PortGroup | null {
|
||||||
{
|
for (let i = 0; i < this.port_groups.length; ++i) {
|
||||||
for (let i = 0; i < this.port_groups.length; ++i)
|
|
||||||
{
|
|
||||||
let port_group = this.port_groups[i];
|
let port_group = this.port_groups[i];
|
||||||
if (port_group.uri === uri)
|
if (port_group.uri === uri) {
|
||||||
{
|
|
||||||
return port_group;
|
return port_group;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
}
|
}
|
||||||
getPortGroupBySymbol(symbol: string): PortGroup | null
|
getPortGroupBySymbol(symbol: string): PortGroup | null {
|
||||||
{
|
for (let i = 0; i < this.port_groups.length; ++i) {
|
||||||
for (let i = 0; i < this.port_groups.length; ++i)
|
|
||||||
{
|
|
||||||
let port_group = this.port_groups[i];
|
let port_group = this.port_groups[i];
|
||||||
if (port_group.symbol === symbol)
|
if (port_group.symbol === symbol) {
|
||||||
{
|
|
||||||
return port_group;
|
return port_group;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -868,13 +821,12 @@ export class UiPlugin implements Deserializable<UiPlugin> {
|
|||||||
port_groups: PortGroup[] = [];
|
port_groups: PortGroup[] = [];
|
||||||
fileProperties: UiFileProperty[] = [];
|
fileProperties: UiFileProperty[] = [];
|
||||||
frequencyPlots: UiFrequencyPlot[] = [];
|
frequencyPlots: UiFrequencyPlot[] = [];
|
||||||
is_vst3 : boolean = false;
|
is_vst3: boolean = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export function makeSplitUiPlugin(): UiPlugin
|
export function makeSplitUiPlugin(): UiPlugin {
|
||||||
{
|
|
||||||
|
|
||||||
return new UiPlugin().deserialize({
|
return new UiPlugin().deserialize({
|
||||||
uri: "uri://two-play/pipedal/pedalboard#Split",
|
uri: "uri://two-play/pipedal/pedalboard#Split",
|
||||||
@@ -900,16 +852,16 @@ export function makeSplitUiPlugin(): UiPlugin
|
|||||||
max_value: 2.0,
|
max_value: 2.0,
|
||||||
enumeration_property: true,
|
enumeration_property: true,
|
||||||
scale_points: [
|
scale_points: [
|
||||||
new ScalePoint().deserialize({value: 0, label: "A/B"}),
|
new ScalePoint().deserialize({ value: 0, label: "A/B" }),
|
||||||
new ScalePoint().deserialize({value: 1, label: "mix"}),
|
new ScalePoint().deserialize({ value: 1, label: "mix" }),
|
||||||
new ScalePoint().deserialize({value: 1, label: "L/R"}),
|
new ScalePoint().deserialize({ value: 1, label: "L/R" }),
|
||||||
],
|
],
|
||||||
is_bypass: false,
|
is_bypass: false,
|
||||||
is_program_controller: false,
|
is_program_controller: false,
|
||||||
custom_units: "",
|
custom_units: "",
|
||||||
connection_optional: false,
|
connection_optional: false,
|
||||||
|
|
||||||
}) ,
|
}),
|
||||||
new UiControl().applyProperties({
|
new UiControl().applyProperties({
|
||||||
symbol: "select",
|
symbol: "select",
|
||||||
name: "Select",
|
name: "Select",
|
||||||
@@ -919,15 +871,15 @@ export function makeSplitUiPlugin(): UiPlugin
|
|||||||
max_value: 1.0,
|
max_value: 1.0,
|
||||||
enumeration_property: true,
|
enumeration_property: true,
|
||||||
scale_points: [
|
scale_points: [
|
||||||
new ScalePoint().deserialize({value: 0, label: "A"}),
|
new ScalePoint().deserialize({ value: 0, label: "A" }),
|
||||||
new ScalePoint().deserialize({value: 1, label: "B"}),
|
new ScalePoint().deserialize({ value: 1, label: "B" }),
|
||||||
],
|
],
|
||||||
is_bypass: false,
|
is_bypass: false,
|
||||||
is_program_controller: false,
|
is_program_controller: false,
|
||||||
custom_units: "",
|
custom_units: "",
|
||||||
connection_optional: false,
|
connection_optional: false,
|
||||||
|
|
||||||
}) ,
|
}),
|
||||||
|
|
||||||
new UiControl().applyProperties({
|
new UiControl().applyProperties({
|
||||||
symbol: "mix",
|
symbol: "mix",
|
||||||
@@ -941,7 +893,7 @@ export function makeSplitUiPlugin(): UiPlugin
|
|||||||
custom_units: "",
|
custom_units: "",
|
||||||
connection_optional: false,
|
connection_optional: false,
|
||||||
|
|
||||||
}) ,
|
}),
|
||||||
new UiControl().applyProperties({
|
new UiControl().applyProperties({
|
||||||
symbol: "panL",
|
symbol: "panL",
|
||||||
name: "Pan Top",
|
name: "Pan Top",
|
||||||
@@ -954,7 +906,7 @@ export function makeSplitUiPlugin(): UiPlugin
|
|||||||
custom_units: "",
|
custom_units: "",
|
||||||
connection_optional: false,
|
connection_optional: false,
|
||||||
|
|
||||||
}) ,
|
}),
|
||||||
new UiControl().applyProperties({
|
new UiControl().applyProperties({
|
||||||
symbol: "volL",
|
symbol: "volL",
|
||||||
name: "Vol Top",
|
name: "Vol Top",
|
||||||
@@ -967,7 +919,7 @@ export function makeSplitUiPlugin(): UiPlugin
|
|||||||
custom_units: "",
|
custom_units: "",
|
||||||
connection_optional: false,
|
connection_optional: false,
|
||||||
|
|
||||||
}) ,
|
}),
|
||||||
new UiControl().applyProperties({
|
new UiControl().applyProperties({
|
||||||
symbol: "panR",
|
symbol: "panR",
|
||||||
name: "Pan Bottom",
|
name: "Pan Bottom",
|
||||||
@@ -980,7 +932,7 @@ export function makeSplitUiPlugin(): UiPlugin
|
|||||||
custom_units: "",
|
custom_units: "",
|
||||||
connection_optional: false,
|
connection_optional: false,
|
||||||
|
|
||||||
}) ,
|
}),
|
||||||
new UiControl().applyProperties({
|
new UiControl().applyProperties({
|
||||||
symbol: "volR",
|
symbol: "volR",
|
||||||
name: "Vol Bottom",
|
name: "Vol Bottom",
|
||||||
@@ -997,7 +949,7 @@ export function makeSplitUiPlugin(): UiPlugin
|
|||||||
port_groups: [],
|
port_groups: [],
|
||||||
fileProperties: [],
|
fileProperties: [],
|
||||||
frequencyPlots: [],
|
frequencyPlots: [],
|
||||||
is_vst3 : false,
|
is_vst3: false,
|
||||||
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
- change icons on gallery in index.html
|
|
||||||
- provide direct link to docs on both landing pages.
|
|
||||||
- feature: redo ./makepackage so that it runs without sudo.
|
- feature: redo ./makepackage so that it runs without sudo.
|
||||||
- Bug: text Cursor hovering over the breadcrumb bar in file property dialog.
|
- Bug: text Cursor hovering over the breadcrumb bar in file property dialog.
|
||||||
- Bug: Turning off wifi-direct sould re-enable NetworkManager.
|
- Bug: Turning off wifi-direct sould re-enable NetworkManager.
|
||||||
|
|||||||
Reference in New Issue
Block a user