inspector.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  3. * You can obtain one at http://mozilla.org/MPL/2.0/. */
  4. "use strict";
  5. /* import-globals-from ../includes.js */
  6. const MIN_INSPECTOR_WIDTH = 300;
  7. // Strings for rendering
  8. const EXPAND_INSPECTOR_STRING = L10N.getStr("expandInspector");
  9. const COLLAPSE_INSPECTOR_STRING = L10N.getStr("collapseInspector");
  10. /**
  11. * Functions handling the audio node inspector UI.
  12. */
  13. var InspectorView = {
  14. _currentNode: null,
  15. // Set up config for view toggling
  16. _collapseString: COLLAPSE_INSPECTOR_STRING,
  17. _expandString: EXPAND_INSPECTOR_STRING,
  18. _toggleEvent: EVENTS.UI_INSPECTOR_TOGGLED,
  19. _animated: true,
  20. _delayed: true,
  21. /**
  22. * Initialization function called when the tool starts up.
  23. */
  24. initialize: function () {
  25. // Set up view controller
  26. this.el = $("#web-audio-inspector");
  27. this.splitter = $("#inspector-splitter");
  28. this.el.setAttribute("width", Services.prefs.getIntPref("devtools.webaudioeditor.inspectorWidth"));
  29. this.button = $("#inspector-pane-toggle");
  30. mixin(this, ToggleMixin);
  31. this.bindToggle();
  32. // Hide inspector view on startup
  33. this.hideImmediately();
  34. this._onNodeSelect = this._onNodeSelect.bind(this);
  35. this._onDestroyNode = this._onDestroyNode.bind(this);
  36. this._onResize = this._onResize.bind(this);
  37. this._onCommandClick = this._onCommandClick.bind(this);
  38. this.splitter.addEventListener("mouseup", this._onResize);
  39. for (let $el of $$("#audio-node-toolbar toolbarbutton")) {
  40. $el.addEventListener("command", this._onCommandClick);
  41. }
  42. window.on(EVENTS.UI_SELECT_NODE, this._onNodeSelect);
  43. gAudioNodes.on("remove", this._onDestroyNode);
  44. },
  45. /**
  46. * Destruction function called when the tool cleans up.
  47. */
  48. destroy: function () {
  49. this.unbindToggle();
  50. this.splitter.removeEventListener("mouseup", this._onResize);
  51. $("#audio-node-toolbar toolbarbutton").removeEventListener("command", this._onCommandClick);
  52. for (let $el of $$("#audio-node-toolbar toolbarbutton")) {
  53. $el.removeEventListener("command", this._onCommandClick);
  54. }
  55. window.off(EVENTS.UI_SELECT_NODE, this._onNodeSelect);
  56. gAudioNodes.off("remove", this._onDestroyNode);
  57. this.el = null;
  58. this.button = null;
  59. this.splitter = null;
  60. },
  61. /**
  62. * Takes a AudioNodeView `node` and sets it as the current
  63. * node and scaffolds the inspector view based off of the new node.
  64. */
  65. setCurrentAudioNode: Task.async(function* (node) {
  66. this._currentNode = node || null;
  67. // If no node selected, set the inspector back to "no AudioNode selected"
  68. // view.
  69. if (!node) {
  70. $("#web-audio-editor-details-pane-empty").removeAttribute("hidden");
  71. $("#web-audio-editor-tabs").setAttribute("hidden", "true");
  72. window.emit(EVENTS.UI_INSPECTOR_NODE_SET, null);
  73. }
  74. // Otherwise load up the tabs view and hide the empty placeholder
  75. else {
  76. $("#web-audio-editor-details-pane-empty").setAttribute("hidden", "true");
  77. $("#web-audio-editor-tabs").removeAttribute("hidden");
  78. this._buildToolbar();
  79. window.emit(EVENTS.UI_INSPECTOR_NODE_SET, this._currentNode.id);
  80. }
  81. }),
  82. /**
  83. * Returns the current AudioNodeView.
  84. */
  85. getCurrentAudioNode: function () {
  86. return this._currentNode;
  87. },
  88. /**
  89. * Empties out the props view.
  90. */
  91. resetUI: function () {
  92. // Set current node to empty to load empty view
  93. this.setCurrentAudioNode();
  94. // Reset AudioNode inspector and hide
  95. this.hideImmediately();
  96. },
  97. _buildToolbar: function () {
  98. let node = this.getCurrentAudioNode();
  99. let bypassable = node.bypassable;
  100. let bypassed = node.isBypassed();
  101. let button = $("#audio-node-toolbar .bypass");
  102. if (!bypassable) {
  103. button.setAttribute("disabled", true);
  104. } else {
  105. button.removeAttribute("disabled");
  106. }
  107. if (!bypassable || bypassed) {
  108. button.removeAttribute("checked");
  109. } else {
  110. button.setAttribute("checked", true);
  111. }
  112. },
  113. /**
  114. * Event handlers
  115. */
  116. /**
  117. * Called on EVENTS.UI_SELECT_NODE, and takes an actorID `id`
  118. * and calls `setCurrentAudioNode` to scaffold the inspector view.
  119. */
  120. _onNodeSelect: function (_, id) {
  121. this.setCurrentAudioNode(gAudioNodes.get(id));
  122. // Ensure inspector is visible when selecting a new node
  123. this.show();
  124. },
  125. _onResize: function () {
  126. if (this.el.getAttribute("width") < MIN_INSPECTOR_WIDTH) {
  127. this.el.setAttribute("width", MIN_INSPECTOR_WIDTH);
  128. }
  129. Services.prefs.setIntPref("devtools.webaudioeditor.inspectorWidth", this.el.getAttribute("width"));
  130. window.emit(EVENTS.UI_INSPECTOR_RESIZE);
  131. },
  132. /**
  133. * Called when `DESTROY_NODE` is fired to remove the node from props view if
  134. * it's currently selected.
  135. */
  136. _onDestroyNode: function (node) {
  137. if (this._currentNode && this._currentNode.id === node.id) {
  138. this.setCurrentAudioNode(null);
  139. }
  140. },
  141. _onCommandClick: function (e) {
  142. let node = this.getCurrentAudioNode();
  143. let button = e.target;
  144. let command = button.getAttribute("data-command");
  145. let checked = button.getAttribute("checked");
  146. if (button.getAttribute("disabled")) {
  147. return;
  148. }
  149. if (command === "bypass") {
  150. if (checked) {
  151. button.removeAttribute("checked");
  152. node.bypass(true);
  153. } else {
  154. button.setAttribute("checked", true);
  155. node.bypass(false);
  156. }
  157. }
  158. }
  159. };