13
0

WS: add plugin parameter controls to the web mixer

This commit is contained in:
Luciano Iam 2020-08-22 21:33:49 +02:00
parent 4fc23fe029
commit 71714cb8b6
7 changed files with 252 additions and 115 deletions

View File

@ -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 {

View File

@ -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();

View File

@ -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
}
});
}

View File

@ -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 {

View File

@ -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;
}

View File

@ -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>

View File

@ -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>