flyout_button.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. /**
  2. * @license
  3. * Visual Blocks Editor
  4. *
  5. * Copyright 2016 Google Inc.
  6. * https://developers.google.com/blockly/
  7. *
  8. * Licensed under the Apache License, Version 2.0 (the "License");
  9. * you may not use this file except in compliance with the License.
  10. * You may obtain a copy of the License at
  11. *
  12. * http://www.apache.org/licenses/LICENSE-2.0
  13. *
  14. * Unless required by applicable law or agreed to in writing, software
  15. * distributed under the License is distributed on an "AS IS" BASIS,
  16. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17. * See the License for the specific language governing permissions and
  18. * limitations under the License.
  19. */
  20. /**
  21. * @fileoverview Class for a button in the flyout.
  22. * @author fenichel@google.com (Rachel Fenichel)
  23. */
  24. 'use strict';
  25. goog.provide('Blockly.FlyoutButton');
  26. goog.require('goog.dom');
  27. goog.require('goog.math.Coordinate');
  28. /**
  29. * Class for a button in the flyout.
  30. * @param {!Blockly.WorkspaceSvg} workspace The workspace in which to place this
  31. * button.
  32. * @param {!Blockly.WorkspaceSvg} targetWorkspace The flyout's target workspace.
  33. * @param {string} text The text to display on the button.
  34. * @param {string} callbackKey The key to use when looking up the callback for a
  35. * click on this button.
  36. * @param {boolean} isLabel Whether this button should be styled as a label.
  37. * @constructor
  38. */
  39. Blockly.FlyoutButton = function(workspace, targetWorkspace, text, callbackKey,
  40. isLabel) {
  41. /**
  42. * @type {!Blockly.WorkspaceSvg}
  43. * @private
  44. */
  45. this.workspace_ = workspace;
  46. /**
  47. * @type {!Blockly.Workspace}
  48. * @private
  49. */
  50. this.targetWorkspace_ = targetWorkspace;
  51. /**
  52. * @type {string}
  53. * @private
  54. */
  55. this.text_ = text;
  56. /**
  57. * @type {!goog.math.Coordinate}
  58. * @private
  59. */
  60. this.position_ = new goog.math.Coordinate(0, 0);
  61. /**
  62. * Function to call when this button is clicked.
  63. * @type {function(!Blockly.FlyoutButton)}
  64. * @private
  65. */
  66. this.callback_ = Blockly.flyoutButtonCallbacks_[callbackKey];
  67. /**
  68. * Whether this button should be styled as a label.
  69. * @type {boolean}
  70. * @private
  71. */
  72. this.isLabel_ = isLabel;
  73. };
  74. /**
  75. * The margin around the text in the button.
  76. */
  77. Blockly.FlyoutButton.MARGIN = 5;
  78. /**
  79. * The width of the button's rect.
  80. * @type {number}
  81. */
  82. Blockly.FlyoutButton.prototype.width = 0;
  83. /**
  84. * The height of the button's rect.
  85. * @type {number}
  86. */
  87. Blockly.FlyoutButton.prototype.height = 0;
  88. /**
  89. * Create the button elements.
  90. * @return {!Element} The button's SVG group.
  91. */
  92. Blockly.FlyoutButton.prototype.createDom = function() {
  93. this.svgGroup_ = Blockly.createSvgElement('g',
  94. {'class': this.isLabel_ ? 'blocklyFlyoutLabel' : 'blocklyFlyoutButton'},
  95. this.workspace_.getCanvas());
  96. if (!this.isLabel_) {
  97. // Shadow rectangle (light source does not mirror in RTL).
  98. var shadow = Blockly.createSvgElement('rect',
  99. {'class': 'blocklyFlyoutButtonShadow',
  100. 'rx': 4, 'ry': 4, 'x': 1, 'y': 1},
  101. this.svgGroup_);
  102. }
  103. // Background rectangle.
  104. var rect = Blockly.createSvgElement('rect',
  105. {'class': this.isLabel_ ?
  106. 'blocklyFlyoutLabelBackground' : 'blocklyFlyoutButtonBackground',
  107. 'rx': 4, 'ry': 4},
  108. this.svgGroup_);
  109. var svgText = Blockly.createSvgElement('text',
  110. {'class': this.isLabel_ ? 'blocklyFlyoutLabelText' : 'blocklyText',
  111. 'x': 0, 'y': 0,
  112. 'text-anchor': 'middle'}, this.svgGroup_);
  113. svgText.textContent = this.text_;
  114. this.width = svgText.getComputedTextLength() +
  115. 2 * Blockly.FlyoutButton.MARGIN;
  116. this.height = 20; // Can't compute it :(
  117. if (!this.isLabel_) {
  118. shadow.setAttribute('width', this.width);
  119. shadow.setAttribute('height', this.height);
  120. }
  121. rect.setAttribute('width', this.width);
  122. rect.setAttribute('height', this.height);
  123. svgText.setAttribute('x', this.width / 2);
  124. svgText.setAttribute('y', this.height - Blockly.FlyoutButton.MARGIN);
  125. this.updateTransform_();
  126. return this.svgGroup_;
  127. };
  128. /**
  129. * Correctly position the flyout button and make it visible.
  130. */
  131. Blockly.FlyoutButton.prototype.show = function() {
  132. this.updateTransform_();
  133. this.svgGroup_.setAttribute('display', 'block');
  134. };
  135. /**
  136. * Update svg attributes to match internal state.
  137. * @private
  138. */
  139. Blockly.FlyoutButton.prototype.updateTransform_ = function() {
  140. this.svgGroup_.setAttribute('transform',
  141. 'translate(' + this.position_.x + ',' + this.position_.y + ')');
  142. };
  143. /**
  144. * Move the button to the given x, y coordinates.
  145. * @param {number} x The new x coordinate.
  146. * @param {number} y The new y coordinate.
  147. */
  148. Blockly.FlyoutButton.prototype.moveTo = function(x, y) {
  149. this.position_.x = x;
  150. this.position_.y = y;
  151. this.updateTransform_();
  152. };
  153. /**
  154. * Get the button's target workspace.
  155. * @return {!Blockly.WorkspaceSvg} The target workspace of the flyout where this
  156. * button resides.
  157. */
  158. Blockly.FlyoutButton.prototype.getTargetWorkspace = function() {
  159. return this.targetWorkspace_;
  160. };
  161. /**
  162. * Dispose of this button.
  163. */
  164. Blockly.FlyoutButton.prototype.dispose = function() {
  165. if (this.svgGroup_) {
  166. goog.dom.removeNode(this.svgGroup_);
  167. this.svgGroup_ = null;
  168. }
  169. this.workspace_ = null;
  170. this.targetWorkspace_ = null;
  171. };
  172. /**
  173. * Do something when the button is clicked.
  174. * @param {!Event} e Mouse up event.
  175. */
  176. Blockly.FlyoutButton.prototype.onMouseUp = function(e) {
  177. // Don't scroll the page.
  178. e.preventDefault();
  179. // Don't propagate mousewheel event (zooming).
  180. e.stopPropagation();
  181. // Stop binding to mouseup and mousemove events--flyout mouseup would normally
  182. // do this, but we're skipping that.
  183. Blockly.Flyout.terminateDrag_();
  184. // Call the callback registered to this button.
  185. if (this.callback_) {
  186. this.callback_(this);
  187. }
  188. };