summaryrefslogtreecommitdiffstats
path: root/devtools/client/webaudioeditor/views/properties.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/client/webaudioeditor/views/properties.js')
-rw-r--r--devtools/client/webaudioeditor/views/properties.js163
1 files changed, 163 insertions, 0 deletions
diff --git a/devtools/client/webaudioeditor/views/properties.js b/devtools/client/webaudioeditor/views/properties.js
new file mode 100644
index 000000000..efd691e5a
--- /dev/null
+++ b/devtools/client/webaudioeditor/views/properties.js
@@ -0,0 +1,163 @@
+/* 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";
+
+const { VariablesView } = require("resource://devtools/client/shared/widgets/VariablesView.jsm");
+
+const GENERIC_VARIABLES_VIEW_SETTINGS = {
+ searchEnabled: false,
+ editableValueTooltip: "",
+ editableNameTooltip: "",
+ preventDisableOnChange: true,
+ preventDescriptorModifiers: false,
+ eval: () => {}
+};
+
+/**
+ * Functions handling the audio node inspector UI.
+ */
+
+var PropertiesView = {
+
+ /**
+ * Initialization function called when the tool starts up.
+ */
+ initialize: function () {
+ this._onEval = this._onEval.bind(this);
+ this._onNodeSet = this._onNodeSet.bind(this);
+
+ window.on(EVENTS.UI_INSPECTOR_NODE_SET, this._onNodeSet);
+ this._propsView = new VariablesView($("#properties-content"), GENERIC_VARIABLES_VIEW_SETTINGS);
+ this._propsView.eval = this._onEval;
+ },
+
+ /**
+ * Destruction function called when the tool cleans up.
+ */
+ destroy: function () {
+ window.off(EVENTS.UI_INSPECTOR_NODE_SET, this._onNodeSet);
+ this._propsView = null;
+ },
+
+ /**
+ * Empties out the props view.
+ */
+ resetUI: function () {
+ this._propsView.empty();
+ this._currentNode = null;
+ },
+
+ /**
+ * Internally sets the current audio node and rebuilds appropriate
+ * views.
+ */
+ _setAudioNode: function (node) {
+ this._currentNode = node;
+ if (this._currentNode) {
+ this._buildPropertiesView();
+ }
+ },
+
+ /**
+ * Reconstructs the `Properties` tab in the inspector
+ * with the `this._currentNode` as it's source.
+ */
+ _buildPropertiesView: Task.async(function* () {
+ let propsView = this._propsView;
+ let node = this._currentNode;
+ propsView.empty();
+
+ let audioParamsScope = propsView.addScope("AudioParams");
+ let props = yield node.getParams();
+
+ // Disable AudioParams VariableView expansion
+ // when there are no props i.e. AudioDestinationNode
+ this._togglePropertiesView(!!props.length);
+
+ props.forEach(({ param, value, flags }) => {
+ let descriptor = {
+ value: value,
+ writable: !flags || !flags.readonly,
+ };
+ let item = audioParamsScope.addItem(param, descriptor);
+
+ // No items should currently display a dropdown
+ item.twisty = false;
+ });
+
+ audioParamsScope.expanded = true;
+
+ window.emit(EVENTS.UI_PROPERTIES_TAB_RENDERED, node.id);
+ }),
+
+ /**
+ * Toggles the display of the "empty" properties view when
+ * node has no properties to display.
+ */
+ _togglePropertiesView: function (show) {
+ let propsView = $("#properties-content");
+ let emptyView = $("#properties-empty");
+ (show ? propsView : emptyView).removeAttribute("hidden");
+ (show ? emptyView : propsView).setAttribute("hidden", "true");
+ },
+
+ /**
+ * Returns the scope for AudioParams in the
+ * VariablesView.
+ *
+ * @return Scope
+ */
+ _getAudioPropertiesScope: function () {
+ return this._propsView.getScopeAtIndex(0);
+ },
+
+ /**
+ * Event handlers
+ */
+
+ /**
+ * Called when the inspector view determines a node is selected.
+ */
+ _onNodeSet: function (_, id) {
+ this._setAudioNode(gAudioNodes.get(id));
+ },
+
+ /**
+ * Executed when an audio prop is changed in the UI.
+ */
+ _onEval: Task.async(function* (variable, value) {
+ let ownerScope = variable.ownerView;
+ let node = this._currentNode;
+ let propName = variable.name;
+ let error;
+
+ if (!variable._initialDescriptor.writable) {
+ error = new Error("Variable " + propName + " is not writable.");
+ } else {
+ // Cast value to proper type
+ try {
+ let number = parseFloat(value);
+ if (!isNaN(number)) {
+ value = number;
+ } else {
+ value = JSON.parse(value);
+ }
+ error = yield node.actor.setParam(propName, value);
+ }
+ catch (e) {
+ error = e;
+ }
+ }
+
+ // TODO figure out how to handle and display set prop errors
+ // and enable `test/brorwser_wa_properties-view-edit.js`
+ // Bug 994258
+ if (!error) {
+ ownerScope.get(propName).setGrip(value);
+ window.emit(EVENTS.UI_SET_PARAM, node.id, propName, value);
+ } else {
+ window.emit(EVENTS.UI_SET_PARAM_ERROR, node.id, propName, value);
+ }
+ })
+};