WS: add plugin parameter controls to the web mixer
This commit is contained in:
parent
4fc23fe029
commit
71714cb8b6
@ -26,7 +26,7 @@
|
||||
/*opacity: 0.2;*/
|
||||
}
|
||||
.toolkit-circular.toolkit-warn > .toolkit-base {
|
||||
opacity: 0.5;
|
||||
/*opacity: 0.5;*/
|
||||
}
|
||||
|
||||
.toolkit-circular > .toolkit-value {
|
||||
@ -34,7 +34,7 @@
|
||||
}
|
||||
.toolkit-circular.toolkit-warn > .toolkit-value {
|
||||
opacity: 1;
|
||||
fill: white;
|
||||
/*fill: white;*/
|
||||
}
|
||||
|
||||
.toolkit-circular > .toolkit-hand {
|
||||
|
@ -17,8 +17,9 @@
|
||||
*/
|
||||
|
||||
import ArdourClient from '/shared/ardour.js';
|
||||
import { createRootContainer, Container, Dialog, Label, Button, DiscreteKnob,
|
||||
LinearKnob, PanKnob, StripGainFader, StripMeter, Toggle } from './tkwidget.js';
|
||||
import { createRootContainer, Container, Dialog, Label, Button, Toggle,
|
||||
DiscreteKnob, LinearKnob, LogKnob, PanKnob,
|
||||
StripGainFader, StripMeter } from './tkwidget.js';
|
||||
|
||||
(() => {
|
||||
|
||||
@ -34,10 +35,6 @@ import { createRootContainer, Container, Dialog, Label, Button, DiscreteKnob,
|
||||
root.removeChild(root.children[0]);
|
||||
}
|
||||
|
||||
const top = new Container();
|
||||
top.id = 'top';
|
||||
top.appendTo(root);
|
||||
|
||||
const mixer = new Container();
|
||||
mixer.id = 'mixer';
|
||||
mixer.appendTo(root);
|
||||
@ -59,83 +56,6 @@ import { createRootContainer, Container, Dialog, Label, Button, DiscreteKnob,
|
||||
ardour.connect();
|
||||
}
|
||||
|
||||
function createStrip (strip, container) {
|
||||
const inserts = new Button();
|
||||
inserts.text = 'ƒ';
|
||||
inserts.appendTo(container);
|
||||
inserts.classList.add('strip-inserts');
|
||||
if (strip.isVca || (strip.plugins.length == 0)) {
|
||||
inserts.classList.add('disabled');
|
||||
} else {
|
||||
inserts.callback = () => openInserts (strip.plugins);
|
||||
}
|
||||
|
||||
const pan = new PanKnob();
|
||||
pan.appendTo(container);
|
||||
|
||||
if (!strip.isVca) {
|
||||
pan.bindTo(strip, 'pan');
|
||||
}
|
||||
|
||||
const mute = new Toggle();
|
||||
mute.text = 'Mute';
|
||||
mute.appendTo(container);
|
||||
mute.bindTo(strip, 'mute');
|
||||
mute.classList.add('strip-mute');
|
||||
|
||||
const meterFader = new Container();
|
||||
meterFader.appendTo(container);
|
||||
meterFader.classList.add('strip-meter-fader');
|
||||
|
||||
const gain = new StripGainFader();
|
||||
gain.appendTo(meterFader);
|
||||
gain.bindTo(strip, 'gain');
|
||||
|
||||
const meter = new StripMeter();
|
||||
meter.appendTo(meterFader);
|
||||
meter.bindTo(strip, 'meter');
|
||||
|
||||
const label = new Label();
|
||||
label.text = strip.name;
|
||||
label.classList.add('strip-label');
|
||||
label.appendTo(container);
|
||||
|
||||
if (strip.isVca) {
|
||||
// hide inserts and pan keeping layout
|
||||
pan.element.style.visibility = 'hidden';
|
||||
inserts.element.style.visibility = 'hidden';
|
||||
}
|
||||
}
|
||||
|
||||
function createStripPlugin (plugin, container) {
|
||||
const enable = new Toggle();
|
||||
enable.appendTo(container);
|
||||
enable.bindTo(plugin, 'enable');
|
||||
|
||||
for (const param of plugin.parameters) {
|
||||
createStripPluginParam(param, container);
|
||||
}
|
||||
}
|
||||
|
||||
function createStripPluginParam (param, container) {
|
||||
let widget;
|
||||
|
||||
if (param.valueType.isBoolean) {
|
||||
widget = new Toggle();
|
||||
} else if (param.valueType.isInteger) {
|
||||
widget = new DiscreteKnob(param.min, param.max);
|
||||
} else if (param.valueType.isDouble) {
|
||||
if (param.isLog) {
|
||||
widget = new LogKnob(param.min, param.max);
|
||||
} else {
|
||||
widget = new LinearKnob(param.min, param.max);
|
||||
}
|
||||
}
|
||||
|
||||
widget.appendTo(container);
|
||||
widget.bindTo(param, 'value');
|
||||
}
|
||||
|
||||
function setupFullscreenButton () {
|
||||
const doc = document.documentElement,
|
||||
button = document.getElementById('fullscreen');
|
||||
@ -162,19 +82,141 @@ import { createRootContainer, Container, Dialog, Label, Button, DiscreteKnob,
|
||||
}
|
||||
}
|
||||
|
||||
function openInserts (plugins) {
|
||||
const dialog = new Dialog();
|
||||
dialog.classList.add('inserts-view');
|
||||
dialog.show();
|
||||
function createStrip (strip, container) {
|
||||
const plugins = new Button();
|
||||
plugins.text = 'ƒ';
|
||||
plugins.classList.add('strip-plugins');
|
||||
plugins.appendTo(container);
|
||||
|
||||
if (strip.isVca || (strip.plugins.length == 0)) {
|
||||
plugins.classList.add('disabled');
|
||||
} else {
|
||||
plugins.callback = () => openPlugins (strip);
|
||||
}
|
||||
|
||||
const pan = new PanKnob();
|
||||
pan.appendTo(container);
|
||||
|
||||
if (!strip.isVca) {
|
||||
pan.bindTo(strip, 'pan');
|
||||
}
|
||||
|
||||
const mute = new Toggle();
|
||||
mute.text = 'Mute';
|
||||
mute.classList.add('strip-mute');
|
||||
mute.appendTo(container);
|
||||
mute.bindTo(strip, 'mute');
|
||||
|
||||
const meterFader = new Container();
|
||||
meterFader.classList.add('strip-meter-fader');
|
||||
meterFader.appendTo(container);
|
||||
|
||||
const gain = new StripGainFader();
|
||||
gain.appendTo(meterFader);
|
||||
gain.bindTo(strip, 'gain');
|
||||
|
||||
const meter = new StripMeter();
|
||||
meter.appendTo(meterFader);
|
||||
meter.bindTo(strip, 'meter');
|
||||
|
||||
const label = new Label();
|
||||
label.text = `WIP: This strip has ${plugins.length} plugins...`;
|
||||
label.appendTo(dialog);
|
||||
label.text = strip.name;
|
||||
label.classList.add('strip-label');
|
||||
label.appendTo(container);
|
||||
|
||||
// TO DO
|
||||
/*for (const plugin of plugins) {
|
||||
createStripPlugin(plugin, container);
|
||||
}*/
|
||||
if (strip.isVca) {
|
||||
// hide plugins and pan keeping layout
|
||||
pan.element.style.visibility = 'hidden';
|
||||
plugins.element.style.visibility = 'hidden';
|
||||
}
|
||||
}
|
||||
|
||||
function openPlugins (strip) {
|
||||
const dialog = new Dialog();
|
||||
dialog.id = 'plugins-dialog';
|
||||
|
||||
const close = new Button();
|
||||
close.id = 'plugins-close';
|
||||
close.icon = 'close';
|
||||
dialog.closeButton = close;
|
||||
|
||||
const plugins = new Container();
|
||||
plugins.id = 'plugins';
|
||||
plugins.appendTo(dialog);
|
||||
|
||||
const label = new Label();
|
||||
label.id = 'plugins-title';
|
||||
label.text = strip.name;
|
||||
label.appendTo(plugins);
|
||||
|
||||
for (const plugin of strip.plugins) {
|
||||
createStripPlugin(plugin, plugins);
|
||||
}
|
||||
|
||||
dialog.onClose = () => {
|
||||
// disconnect all parameters
|
||||
for (const plugin of strip.plugins) {
|
||||
for (const param of plugin.parameters) {
|
||||
param.removeObserver();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
function createStripPlugin (plugin, dialog) {
|
||||
const enableAndName = new Container();
|
||||
enableAndName.appendTo(dialog);
|
||||
|
||||
const enable = new Toggle();
|
||||
enable.setIcons('unchecked', 'checked');
|
||||
enable.appendTo(enableAndName);
|
||||
enable.bindTo(plugin, 'enable');
|
||||
|
||||
const label = new Label();
|
||||
label.text = plugin.name;
|
||||
label.appendTo(enableAndName);
|
||||
|
||||
const container = new Container();
|
||||
container.classList.add('plugin-parameters');
|
||||
container.appendTo(dialog);
|
||||
|
||||
for (const param of plugin.parameters) {
|
||||
createStripPluginParam(param, container);
|
||||
}
|
||||
}
|
||||
|
||||
function createStripPluginParam (param, container) {
|
||||
let widget;
|
||||
|
||||
if (param.valueType.isBoolean) {
|
||||
widget = new Toggle();
|
||||
widget.setIcons('unchecked', 'checked');
|
||||
} else if (param.valueType.isInteger) {
|
||||
widget = new DiscreteKnob(param.min, param.max);
|
||||
} else if (param.valueType.isDouble) {
|
||||
if (param.isLog) {
|
||||
widget = new LogKnob(param.min, param.max);
|
||||
} else {
|
||||
widget = new LinearKnob(param.min, param.max);
|
||||
}
|
||||
}
|
||||
|
||||
const labeledWidget = new Container();
|
||||
labeledWidget.classList.add('plugin-parameter');
|
||||
labeledWidget.appendTo(container);
|
||||
|
||||
const widgetContainer = new Container();
|
||||
widgetContainer.classList.add('plugin-parameter-widget');
|
||||
widgetContainer.appendTo(labeledWidget);
|
||||
|
||||
widget.appendTo(widgetContainer);
|
||||
widget.bindTo(param, 'value');
|
||||
|
||||
const label = new Label();
|
||||
label.text = param.name;
|
||||
label.appendTo(labeledWidget);
|
||||
}
|
||||
|
||||
main();
|
||||
|
@ -135,6 +135,11 @@ export class Dialog extends BaseDialog {
|
||||
return this.tk.element;
|
||||
}
|
||||
|
||||
set closeButton (button) {
|
||||
button.callback = () => this.close();
|
||||
this.appendChild(button);
|
||||
}
|
||||
|
||||
appendChild (child) {
|
||||
super.appendChild(child);
|
||||
this.tk.append_child(child.tk);
|
||||
@ -146,9 +151,14 @@ export class Dialog extends BaseDialog {
|
||||
// handler or setTimeout() is used here
|
||||
setTimeout(() => {
|
||||
this.tk.set('display_state', 'show');
|
||||
this.tk.add_event('close', (ev) => this.onClose(ev));
|
||||
}, 0);
|
||||
}
|
||||
|
||||
close () {
|
||||
this.tk.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class Button extends Control {
|
||||
@ -162,6 +172,12 @@ export class Button extends Control {
|
||||
this.tk.set('label', text);
|
||||
}
|
||||
|
||||
set icon (icon) {
|
||||
// see toolkit/styles/Toolkit.html
|
||||
this.tk.set('icon', icon);
|
||||
this.element.style.border = 'none';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class Toggle extends Control {
|
||||
@ -183,6 +199,12 @@ export class Toggle extends Control {
|
||||
this.tk.set('state', val);
|
||||
}
|
||||
|
||||
setIcons (inactive, active) {
|
||||
this.tk.set('icon', inactive);
|
||||
this.tk.set('icon_active', active);
|
||||
this.element.style.border = 'none';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class StripGainFader extends RangeControl {
|
||||
@ -220,7 +242,11 @@ export class LinearKnob extends Knob {
|
||||
super({
|
||||
scale: 'linear',
|
||||
min: min,
|
||||
max: max
|
||||
max: max,
|
||||
hand: {
|
||||
width: 5,
|
||||
length: 15
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -230,9 +256,13 @@ export class LogKnob extends Knob {
|
||||
|
||||
constructor (min, max) {
|
||||
super({
|
||||
scale: 'log2',
|
||||
scale: 'frequency',
|
||||
min: min,
|
||||
max: max
|
||||
max: max,
|
||||
hand: {
|
||||
width: 5,
|
||||
length: 15
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -245,7 +275,11 @@ export class DiscreteKnob extends Knob {
|
||||
scale: 'linear',
|
||||
min: min,
|
||||
max: max,
|
||||
snap: step || 1
|
||||
snap: step || 1,
|
||||
hand: {
|
||||
width: 5,
|
||||
length: 15
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -62,10 +62,22 @@ export class BaseDialog extends BaseContainer {
|
||||
this.children = [];
|
||||
}
|
||||
|
||||
set closeButton (button) {
|
||||
// empty
|
||||
}
|
||||
|
||||
show () {
|
||||
// empty
|
||||
}
|
||||
|
||||
close () {
|
||||
// empty
|
||||
}
|
||||
|
||||
onClose () {
|
||||
// empty
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class BaseControl extends BaseWidget {
|
||||
|
@ -45,17 +45,14 @@ div {
|
||||
background-image: url('expand.svg');
|
||||
}
|
||||
|
||||
#top {
|
||||
height: 10vh;
|
||||
}
|
||||
|
||||
#mixer {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
padding-bottom: 10vh;
|
||||
padding: 10vh 0;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
@ -97,24 +94,76 @@ div {
|
||||
background-color: inherit;
|
||||
}
|
||||
|
||||
.strip-inserts {
|
||||
.strip-plugins {
|
||||
color: rgb(248,248,242);
|
||||
border: 1px solid rgb(36,36,36);
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.strip-inserts.disabled {
|
||||
.strip-plugins.disabled {
|
||||
color: rgb(36,36,36);
|
||||
}
|
||||
|
||||
.inserts-view {
|
||||
width: 100%;
|
||||
max-width: 666px;
|
||||
height: 100%;
|
||||
max-height: 500px;
|
||||
background: rgb(62,61,61);
|
||||
#plugins-dialog {
|
||||
width: 60%;
|
||||
min-width: 666px;
|
||||
height: 80%;
|
||||
min-height: 500px;
|
||||
background: rgb(52,51,51);
|
||||
border: none;
|
||||
/* absolute positioning cannot be disabled for tk dialogs */
|
||||
left: inherit !important;
|
||||
top: inherit !important;
|
||||
}
|
||||
|
||||
#plugins {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 1em;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
#plugins-title {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
font-size: 1.25em;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
#plugins-close {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
padding: 5px;
|
||||
opacity: 0.5;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.plugin-parameters {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.plugin-parameters:not(:last-child) {
|
||||
border-bottom: solid 1px rgba(255,255,255,0.1);
|
||||
}
|
||||
|
||||
.plugin-parameter {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin: 1em;
|
||||
}
|
||||
|
||||
.plugin-parameter-widget {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-grow: 1;
|
||||
justify-content: center;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<WebSurface>
|
||||
<Name value="Mixer (Work In Progress)"/>
|
||||
<Name value="Mixer"/>
|
||||
<Description value="Provides basic mixer controls like gain, pan, mute and effects."/>
|
||||
<Version value="0.2.0"/>
|
||||
<Version value="1.0.0"/>
|
||||
</WebSurface>
|
||||
|
@ -2,5 +2,5 @@
|
||||
<WebSurface>
|
||||
<Name value="Transport"/>
|
||||
<Description value="Provides basic transport control like play, pause and record"/>
|
||||
<Version value="0.1.2"/>
|
||||
<Version value="1.0.0"/>
|
||||
</WebSurface>
|
||||
|
Loading…
Reference in New Issue
Block a user