From 71714cb8b6af29892eeafa318e3d539f859727ed Mon Sep 17 00:00:00 2001 From: Luciano Iam Date: Sat, 22 Aug 2020 21:33:49 +0200 Subject: [PATCH] WS: add plugin parameter controls to the web mixer --- .../ardour-toolkit-theme/css/circular.css | 4 +- share/web_surfaces/builtin/mixer/js/main.js | 228 +++++++++++------- .../web_surfaces/builtin/mixer/js/tkwidget.js | 42 +++- share/web_surfaces/builtin/mixer/js/widget.js | 12 + share/web_surfaces/builtin/mixer/main.css | 75 +++++- share/web_surfaces/builtin/mixer/manifest.xml | 4 +- .../builtin/transport/manifest.xml | 2 +- 7 files changed, 252 insertions(+), 115 deletions(-) diff --git a/share/web_surfaces/builtin/mixer/ardour-toolkit-theme/css/circular.css b/share/web_surfaces/builtin/mixer/ardour-toolkit-theme/css/circular.css index dc32918cc8..8bc61eb21d 100644 --- a/share/web_surfaces/builtin/mixer/ardour-toolkit-theme/css/circular.css +++ b/share/web_surfaces/builtin/mixer/ardour-toolkit-theme/css/circular.css @@ -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 { diff --git a/share/web_surfaces/builtin/mixer/js/main.js b/share/web_surfaces/builtin/mixer/js/main.js index 8427e89aba..05478f4903 100644 --- a/share/web_surfaces/builtin/mixer/js/main.js +++ b/share/web_surfaces/builtin/mixer/js/main.js @@ -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(); diff --git a/share/web_surfaces/builtin/mixer/js/tkwidget.js b/share/web_surfaces/builtin/mixer/js/tkwidget.js index 1769d677b2..444b2d2c05 100644 --- a/share/web_surfaces/builtin/mixer/js/tkwidget.js +++ b/share/web_surfaces/builtin/mixer/js/tkwidget.js @@ -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 + } }); } diff --git a/share/web_surfaces/builtin/mixer/js/widget.js b/share/web_surfaces/builtin/mixer/js/widget.js index cdffc7c71b..f31dc5ec0e 100644 --- a/share/web_surfaces/builtin/mixer/js/widget.js +++ b/share/web_surfaces/builtin/mixer/js/widget.js @@ -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 { diff --git a/share/web_surfaces/builtin/mixer/main.css b/share/web_surfaces/builtin/mixer/main.css index c086060b1c..c1efc378f1 100644 --- a/share/web_surfaces/builtin/mixer/main.css +++ b/share/web_surfaces/builtin/mixer/main.css @@ -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; +} diff --git a/share/web_surfaces/builtin/mixer/manifest.xml b/share/web_surfaces/builtin/mixer/manifest.xml index 00ce953026..380f5b54ac 100644 --- a/share/web_surfaces/builtin/mixer/manifest.xml +++ b/share/web_surfaces/builtin/mixer/manifest.xml @@ -1,6 +1,6 @@ - + - + diff --git a/share/web_surfaces/builtin/transport/manifest.xml b/share/web_surfaces/builtin/transport/manifest.xml index e45b147bcd..9daaa83ed0 100644 --- a/share/web_surfaces/builtin/transport/manifest.xml +++ b/share/web_surfaces/builtin/transport/manifest.xml @@ -2,5 +2,5 @@ - +