/** * @license * Visual Blocks Editor * * Copyright 2016 Google Inc. * https://developers.google.com/blockly/ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * @fileoverview Methods for graphically rendering a block as SVG. * @author fenichel@google.com (Rachel Fenichel) */ 'use strict'; goog.provide('Blockly.BlockSvg.render'); goog.require('Blockly.blockRendering'); goog.require('Blockly.BlockSvg'); goog.require('Blockly.utils.dom'); // UI constants for rendering blocks. /** * Vertical space between elements. * @const */ Blockly.BlockSvg.SEP_SPACE_Y = 10; /** * Minimum height of a block. * @const */ Blockly.BlockSvg.MIN_BLOCK_Y = 25; /** * Width of horizontal puzzle tab. * @const */ Blockly.BlockSvg.TAB_WIDTH = 8; /** * Do blocks with no previous or output connections have a 'hat' on top? * @const */ Blockly.BlockSvg.START_HAT = false; /** * Returns a bounding box describing the dimensions of this block * and any blocks stacked below it. * @return {!{height: number, width: number}} Object with height and width * properties in workspace units. */ Blockly.BlockSvg.prototype.getHeightWidth = function() { var height = this.height; var width = this.width; // Recursively add size of subsequent blocks. var nextBlock = this.getNextBlock(); if (nextBlock) { var nextHeightWidth = nextBlock.getHeightWidth(); height += nextHeightWidth.height - 4; // Height of tab. width = Math.max(width, nextHeightWidth.width); } return {height: height, width: width}; }; /** * Position an new block correctly, so that it doesn't move the existing block * when connected to it. * @param {!Blockly.Block} newBlock The block to position - either the first * block in a dragged stack or an insertion marker. * @param {!Blockly.Connection} newConnection The connection on the new block's * stack - either a connection on newBlock, or the last NEXT_STATEMENT * connection on the stack if the stack's being dropped before another * block. * @param {!Blockly.Connection} existingConnection The connection on the * existing block, which newBlock should line up with. */ Blockly.BlockSvg.prototype.positionNewBlock = function(newBlock, newConnection, existingConnection) { // We only need to position the new block if it's before the existing one, // otherwise its position is set by the previous block. if (newConnection.type == Blockly.NEXT_STATEMENT || newConnection.type == Blockly.INPUT_VALUE) { var dx = existingConnection.x_ - newConnection.x_; var dy = existingConnection.y_ - newConnection.y_; newBlock.moveBy(dx, dy); } }; /** * Visual effect to show that if the dragging block is dropped, this block will * be replaced. If a shadow block, it will disappear. Otherwise it will bump. * @param {boolean} add True if highlighting should be added. */ Blockly.BlockSvg.prototype.highlightForReplacement = function(add) { if (add) { Blockly.utils.dom.addClass(/** @type {!Element} */ (this.svgGroup_), 'blocklyReplaceable'); } else { Blockly.utils.dom.removeClass(/** @type {!Element} */ (this.svgGroup_), 'blocklyReplaceable'); } };