diff options
Diffstat (limited to 'devtools/client/webaudioeditor/views/automation.js')
-rw-r--r-- | devtools/client/webaudioeditor/views/automation.js | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/devtools/client/webaudioeditor/views/automation.js b/devtools/client/webaudioeditor/views/automation.js new file mode 100644 index 000000000..2fab262bd --- /dev/null +++ b/devtools/client/webaudioeditor/views/automation.js @@ -0,0 +1,159 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ +"use strict"; + +/** + * Functions handling the audio node inspector UI. + */ + +var AutomationView = { + + /** + * Initialization function called when the tool starts up. + */ + initialize: function () { + this._buttons = $("#automation-param-toolbar-buttons"); + this.graph = new LineGraphWidget($("#automation-graph"), { avg: false }); + this.graph.selectionEnabled = false; + + this._onButtonClick = this._onButtonClick.bind(this); + this._onNodeSet = this._onNodeSet.bind(this); + this._onResize = this._onResize.bind(this); + + this._buttons.addEventListener("click", this._onButtonClick); + window.on(EVENTS.UI_INSPECTOR_RESIZE, this._onResize); + window.on(EVENTS.UI_INSPECTOR_NODE_SET, this._onNodeSet); + }, + + /** + * Destruction function called when the tool cleans up. + */ + destroy: function () { + this._buttons.removeEventListener("click", this._onButtonClick); + window.off(EVENTS.UI_INSPECTOR_RESIZE, this._onResize); + window.off(EVENTS.UI_INSPECTOR_NODE_SET, this._onNodeSet); + }, + + /** + * Empties out the props view. + */ + resetUI: function () { + this._currentNode = null; + }, + + /** + * On a new node selection, create the Automation panel for + * that specific node. + */ + build: Task.async(function* () { + let node = this._currentNode; + + let props = yield node.getParams(); + let params = props.filter(({ flags }) => flags && flags.param); + + this._createParamButtons(params); + + this._selectedParamName = params[0] ? params[0].param : null; + this.render(); + }), + + /** + * Renders the graph for specified `paramName`. Called when + * the parameter view is changed, or when new param data events + * are fired for the currently specified param. + */ + render: Task.async(function* () { + let node = this._currentNode; + let paramName = this._selectedParamName; + // Escape if either node or parameter name does not exist. + if (!node || !paramName) { + this._setState("no-params"); + window.emit(EVENTS.UI_AUTOMATION_TAB_RENDERED, null); + return; + } + + let { values, events } = yield node.getAutomationData(paramName); + this._setState(events.length ? "show" : "no-events"); + yield this.graph.setDataWhenReady(values); + window.emit(EVENTS.UI_AUTOMATION_TAB_RENDERED, node.id); + }), + + /** + * Create the buttons for each AudioParam, that when clicked, + * render the graph for that AudioParam. + */ + _createParamButtons: function (params) { + this._buttons.innerHTML = ""; + params.forEach((param, i) => { + let button = document.createElement("toolbarbutton"); + button.setAttribute("class", "devtools-toolbarbutton automation-param-button"); + button.setAttribute("data-param", param.param); + // Set label to the parameter name, should not be L10N'd + button.setAttribute("label", param.param); + + // If first button, set to 'selected' for styling + if (i === 0) { + button.setAttribute("selected", true); + } + + this._buttons.appendChild(button); + }); + }, + + /** + * Internally sets the current audio node and rebuilds appropriate + * views. + */ + _setAudioNode: function (node) { + this._currentNode = node; + if (this._currentNode) { + this.build(); + } + }, + + /** + * Toggles the subviews to display messages whether or not + * the audio node has no AudioParams, no automation events, or + * shows the graph. + */ + _setState: function (state) { + let contentView = $("#automation-content"); + let emptyView = $("#automation-empty"); + + let graphView = $("#automation-graph-container"); + let noEventsView = $("#automation-no-events"); + + contentView.hidden = state === "no-params"; + emptyView.hidden = state !== "no-params"; + + graphView.hidden = state !== "show"; + noEventsView.hidden = state !== "no-events"; + }, + + /** + * Event handlers + */ + + _onButtonClick: function (e) { + Array.forEach($$(".automation-param-button"), $btn => $btn.removeAttribute("selected")); + let paramName = e.target.getAttribute("data-param"); + e.target.setAttribute("selected", true); + this._selectedParamName = paramName; + this.render(); + }, + + /** + * Called when the inspector is resized. + */ + _onResize: function () { + this.graph.refresh(); + }, + + /** + * Called when the inspector view determines a node is selected. + */ + _onNodeSet: function (_, id) { + this._setAudioNode(id != null ? gAudioNodes.get(id) : null); + } +}; |