block_option.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /**
  2. * @license
  3. * Blockly Demos: Block Factory
  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 Javascript for the BlockOption class, used to represent each of
  22. * the various blocks that you may select. Each block option has a checkbox,
  23. * a label, and a preview workspace through which to view the block.
  24. *
  25. * @author quachtina96 (Tina Quach)
  26. */
  27. 'use strict';
  28. goog.provide('BlockOption');
  29. goog.require('goog.dom');
  30. /**
  31. * BlockOption Class
  32. * A block option includes checkbox, label, and div element that shows a preview
  33. * of the block.
  34. * @param {!Element} blockSelector Scrollable div that will contain the
  35. * block options for the selector.
  36. * @param {string} blockType Type of block for which to create an option.
  37. * @param {!Element} previewBlockXml XML element containing the preview block.
  38. * @constructor
  39. */
  40. var BlockOption = function(blockSelector, blockType, previewBlockXml) {
  41. // The div to contain the block option.
  42. this.blockSelector = blockSelector;
  43. // The type of block represented by the option.
  44. this.blockType = blockType;
  45. // The checkbox for the option. Set in createDom.
  46. this.checkbox = null;
  47. // The dom for the option. Set in createDom.
  48. this.dom = null;
  49. // Xml element containing the preview block.
  50. this.previewBlockXml = previewBlockXml;
  51. // Workspace containing preview of block. Set upon injection of workspace in
  52. // showPreviewBlock.
  53. this.previewWorkspace = null;
  54. // Whether or not block the option is selected.
  55. this.selected = false;
  56. // Using this.selected rather than this.checkbox.checked allows for proper
  57. // handling of click events on the block option; Without this, clicking
  58. // directly on the checkbox does not toggle selection.
  59. };
  60. /**
  61. * Creates the dom for a single block option. Includes checkbox, label, and div
  62. * in which to inject the preview block.
  63. * @return {!Element} Root node of the selector dom which consists of a
  64. * checkbox, a label, and a fixed size preview workspace per block.
  65. */
  66. BlockOption.prototype.createDom = function() {
  67. // Create the div for the block option.
  68. var blockOptContainer = goog.dom.createDom('div', {
  69. 'id': this.blockType,
  70. 'class': 'blockOption'
  71. }, ''); // Empty quotes for empty div.
  72. // Create and append div in which to inject the workspace for viewing the
  73. // block option.
  74. var blockOptionPreview = goog.dom.createDom('div', {
  75. 'id' : this.blockType + '_workspace',
  76. 'class': 'blockOption_preview'
  77. }, '');
  78. blockOptContainer.appendChild(blockOptionPreview);
  79. // Create and append container to hold checkbox and label.
  80. var checkLabelContainer = goog.dom.createDom('div', {
  81. 'class': 'blockOption_checkLabel'
  82. }, '');
  83. blockOptContainer.appendChild(checkLabelContainer);
  84. // Create and append container for checkbox.
  85. var checkContainer = goog.dom.createDom('div', {
  86. 'class': 'blockOption_check'
  87. }, '');
  88. checkLabelContainer.appendChild(checkContainer);
  89. // Create and append checkbox.
  90. this.checkbox = goog.dom.createDom('input', {
  91. 'type': 'checkbox',
  92. 'id': this.blockType + '_check'
  93. }, '');
  94. checkContainer.appendChild(this.checkbox);
  95. // Create and append container for block label.
  96. var labelContainer = goog.dom.createDom('div', {
  97. 'class': 'blockOption_label'
  98. }, '');
  99. checkLabelContainer.appendChild(labelContainer);
  100. // Create and append text node for the label.
  101. var labelText = goog.dom.createDom('p', {
  102. 'id': this.blockType + '_text'
  103. }, this.blockType);
  104. labelContainer.appendChild(labelText);
  105. this.dom = blockOptContainer;
  106. return this.dom;
  107. };
  108. /**
  109. * Injects a workspace containing the block into the block option's preview div.
  110. */
  111. BlockOption.prototype.showPreviewBlock = function() {
  112. // Get ID of preview workspace.
  113. var blockOptPreviewID = this.dom.id + '_workspace';
  114. // Inject preview block.
  115. var workspace = Blockly.inject(blockOptPreviewID, {readOnly:true});
  116. Blockly.Xml.domToWorkspace(this.previewBlockXml, workspace);
  117. this.previewWorkspace = workspace;
  118. // Center the preview block in the workspace.
  119. this.centerBlock();
  120. };
  121. /**
  122. * Centers the preview block in the workspace.
  123. */
  124. BlockOption.prototype.centerBlock = function() {
  125. // Get metrics.
  126. var block = this.previewWorkspace.getTopBlocks()[0];
  127. var blockMetrics = block.getHeightWidth();
  128. var blockCoordinates = block.getRelativeToSurfaceXY();
  129. var workspaceMetrics = this.previewWorkspace.getMetrics();
  130. // Calculate new coordinates.
  131. var x = workspaceMetrics.viewWidth/2 - blockMetrics['width']/2 -
  132. blockCoordinates.x;
  133. var y = workspaceMetrics.viewHeight/2 - blockMetrics['height']/2 -
  134. blockCoordinates.y;
  135. // Move block.
  136. block.moveBy(x, y);
  137. };
  138. /**
  139. * Selects or deselects the block option.
  140. * @param {!boolean} selected True if selecting option, false if deselecting
  141. * option.
  142. */
  143. BlockOption.prototype.setSelected = function(selected) {
  144. this.selected = selected;
  145. if (this.checkbox) {
  146. this.checkbox.checked = selected;
  147. }
  148. };
  149. /**
  150. * Returns boolean telling whether or not block is selected.
  151. * @return {!boolean} True if selecting option, false if deselecting
  152. * option.
  153. */
  154. BlockOption.prototype.isSelected = function() {
  155. return this.selected;
  156. };