From 06a882348b47fd91225dd37ce4b5545e584d0f03 Mon Sep 17 00:00:00 2001 From: Sam El-Husseini Date: Fri, 30 Aug 2019 18:11:01 -0700 Subject: [PATCH] Render round right corners in zelos. (#2938) * Render round right corners in zelos. --- blockly_uncompressed.js | 5 +- core/renderers/common/block_rendering.js | 3 + core/renderers/common/drawer.js | 2 +- core/renderers/common/info.js | 5 +- core/renderers/measurables/row_elements.js | 19 +-- core/renderers/measurables/rows.js | 37 ++++-- core/renderers/zelos/constants.js | 102 +++++++++++++--- core/renderers/zelos/drawer.js | 60 ++++++++++ core/renderers/zelos/info.js | 43 +++++++ core/renderers/zelos/measurables/rows.js | 131 +++++++++++++++++++++ 10 files changed, 369 insertions(+), 38 deletions(-) create mode 100644 core/renderers/zelos/measurables/rows.js diff --git a/blockly_uncompressed.js b/blockly_uncompressed.js index b6e7563c2..00564bffc 100644 --- a/blockly_uncompressed.js +++ b/blockly_uncompressed.js @@ -109,7 +109,8 @@ goog.addDependency("../../../" + dir + "/core/renderers/measurables/rows.js", [' goog.addDependency("../../../" + dir + "/core/renderers/thrasos/info.js", ['Blockly.thrasos', 'Blockly.thrasos.RenderInfo'], ['Blockly.blockRendering.RenderInfo', 'Blockly.blockRendering.Measurable', 'Blockly.blockRendering.BottomRow', 'Blockly.blockRendering.InputRow', 'Blockly.blockRendering.Row', 'Blockly.blockRendering.SpacerRow', 'Blockly.blockRendering.TopRow', 'Blockly.blockRendering.InlineInput', 'Blockly.blockRendering.ExternalValueInput', 'Blockly.blockRendering.StatementInput', 'Blockly.blockRendering.PreviousConnection', 'Blockly.blockRendering.NextConnection', 'Blockly.blockRendering.OutputConnection', 'Blockly.RenderedConnection']); goog.addDependency("../../../" + dir + "/core/renderers/zelos/constants.js", ['Blockly.zelos.ConstantProvider'], ['Blockly.blockRendering.ConstantProvider', 'Blockly.utils.svgPaths']); goog.addDependency("../../../" + dir + "/core/renderers/zelos/drawer.js", ['Blockly.zelos.Drawer'], ['Blockly.blockRendering.ConstantProvider', 'Blockly.blockRendering.Drawer', 'Blockly.zelos.RenderInfo']); -goog.addDependency("../../../" + dir + "/core/renderers/zelos/info.js", ['Blockly.zelos', 'Blockly.zelos.RenderInfo'], ['Blockly.blockRendering.RenderInfo', 'Blockly.blockRendering.Measurable', 'Blockly.blockRendering.BottomRow', 'Blockly.blockRendering.InputRow', 'Blockly.blockRendering.Row', 'Blockly.blockRendering.SpacerRow', 'Blockly.blockRendering.TopRow', 'Blockly.blockRendering.InlineInput', 'Blockly.blockRendering.ExternalValueInput', 'Blockly.blockRendering.StatementInput', 'Blockly.blockRendering.PreviousConnection', 'Blockly.blockRendering.NextConnection', 'Blockly.blockRendering.OutputConnection', 'Blockly.RenderedConnection']); +goog.addDependency("../../../" + dir + "/core/renderers/zelos/info.js", ['Blockly.zelos', 'Blockly.zelos.RenderInfo'], ['Blockly.blockRendering.RenderInfo', 'Blockly.blockRendering.Measurable', 'Blockly.blockRendering.BottomRow', 'Blockly.blockRendering.InputRow', 'Blockly.blockRendering.Row', 'Blockly.blockRendering.SpacerRow', 'Blockly.blockRendering.TopRow', 'Blockly.blockRendering.InlineInput', 'Blockly.blockRendering.ExternalValueInput', 'Blockly.blockRendering.StatementInput', 'Blockly.blockRendering.PreviousConnection', 'Blockly.blockRendering.NextConnection', 'Blockly.blockRendering.OutputConnection', 'Blockly.RenderedConnection', 'Blockly.zelos.BottomRow', 'Blockly.zelos.TopRow']); +goog.addDependency("../../../" + dir + "/core/renderers/zelos/measurables/rows.js", ['Blockly.zelos.BottomRow', 'Blockly.zelos.TopRow'], ['Blockly.blockRendering.BottomRow', 'Blockly.blockRendering.TopRow']); goog.addDependency("../../../" + dir + "/core/scrollbar.js", ['Blockly.Scrollbar', 'Blockly.ScrollbarPair'], ['Blockly.Touch', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.dom']); goog.addDependency("../../../" + dir + "/core/theme.js", ['Blockly.Theme'], []); goog.addDependency("../../../" + dir + "/core/theme/classic.js", ['Blockly.Themes.Classic'], ['Blockly.Theme']); @@ -322,9 +323,11 @@ goog.require('Blockly.utils.uiMenu'); goog.require('Blockly.utils.userAgent'); goog.require('Blockly.utils.xml'); goog.require('Blockly.zelos'); +goog.require('Blockly.zelos.BottomRow'); goog.require('Blockly.zelos.ConstantProvider'); goog.require('Blockly.zelos.Drawer'); goog.require('Blockly.zelos.RenderInfo'); +goog.require('Blockly.zelos.TopRow'); delete root.BLOCKLY_DIR; delete root.BLOCKLY_BOOT; diff --git a/core/renderers/common/block_rendering.js b/core/renderers/common/block_rendering.js index fa07e66e7..7834431b6 100644 --- a/core/renderers/common/block_rendering.js +++ b/core/renderers/common/block_rendering.js @@ -83,12 +83,15 @@ Blockly.blockRendering.render = function(block) { } if (Blockly.blockRendering.rendererName == 'geras') { var info = new Blockly.geras.RenderInfo(block); + info.measure(); new Blockly.geras.Drawer(block, info).draw(); } else if (Blockly.blockRendering.rendererName == 'thrasos') { var info = new Blockly.thrasos.RenderInfo(block); + info.measure(); new Blockly.blockRendering.Drawer(block, info).draw(); } else if (Blockly.blockRendering.rendererName == 'zelos') { var info = new Blockly.zelos.RenderInfo(block); + info.measure(); new Blockly.zelos.Drawer(block, info).draw(); } }; diff --git a/core/renderers/common/drawer.js b/core/renderers/common/drawer.js index 90d57c39c..621e2aa33 100644 --- a/core/renderers/common/drawer.js +++ b/core/renderers/common/drawer.js @@ -110,7 +110,7 @@ Blockly.blockRendering.Drawer.prototype.hideHiddenIcons_ = function() { */ Blockly.blockRendering.Drawer.prototype.drawOutline_ = function() { this.drawTop_(); - for (var r = 1; r < this.info_.rows.length - 1; r++) { + for (var r = 1; r < this.info_.rows.length - 2; r++) { var row = this.info_.rows[r]; if (row.hasJaggedEdge) { this.drawJaggedEdge_(row); diff --git a/core/renderers/common/info.js b/core/renderers/common/info.js index 30485fe88..74a818357 100644 --- a/core/renderers/common/info.js +++ b/core/renderers/common/info.js @@ -147,7 +147,6 @@ Blockly.blockRendering.RenderInfo = function(block) { this.startY = 0; this.constants_ = Blockly.blockRendering.getConstants(); - this.measure_(); }; /** @@ -158,9 +157,9 @@ Blockly.blockRendering.RenderInfo = function(block) { * may choose to rerender when getSize() is called). However, calling it * repeatedly may be expensive. * - * @protected + * @package */ -Blockly.blockRendering.RenderInfo.prototype.measure_ = function() { +Blockly.blockRendering.RenderInfo.prototype.measure = function() { this.createRows_(); this.addElemSpacing_(); this.computeBounds_(); diff --git a/core/renderers/measurables/row_elements.js b/core/renderers/measurables/row_elements.js index 248feb25b..21827ce55 100644 --- a/core/renderers/measurables/row_elements.js +++ b/core/renderers/measurables/row_elements.js @@ -42,7 +42,8 @@ Blockly.blockRendering.JaggedEdge = function() { this.height = this.constants_.JAGGED_TEETH.height; this.width = this.constants_.JAGGED_TEETH.width; }; -goog.inherits(Blockly.blockRendering.JaggedEdge, Blockly.blockRendering.Measurable); +goog.inherits(Blockly.blockRendering.JaggedEdge, + Blockly.blockRendering.Measurable); /** @@ -88,36 +89,40 @@ goog.inherits(Blockly.blockRendering.Hat, Blockly.blockRendering.Measurable); /** * An object containing information about the space a square corner takes up * during rendering. + * @param {string=} opt_position The position of this corner. * @package * @constructor * @extends {Blockly.blockRendering.Measurable} */ -Blockly.blockRendering.SquareCorner = function() { +Blockly.blockRendering.SquareCorner = function(opt_position) { Blockly.blockRendering.SquareCorner.superClass_.constructor.call(this); - this.type = 'square corner'; + this.type = 'square corner' + (opt_position ? ' ' + opt_position : ''); this.height = this.constants_.NOTCH.height; this.width = this.constants_.NO_PADDING; }; -goog.inherits(Blockly.blockRendering.SquareCorner, Blockly.blockRendering.Measurable); +goog.inherits(Blockly.blockRendering.SquareCorner, + Blockly.blockRendering.Measurable); /** * An object containing information about the space a rounded corner takes up * during rendering. + * @param {string=} opt_position The position of this corner. * @package * @constructor * @extends {Blockly.blockRendering.Measurable} */ -Blockly.blockRendering.RoundCorner = function() { +Blockly.blockRendering.RoundCorner = function(opt_position) { Blockly.blockRendering.RoundCorner.superClass_.constructor.call(this); - this.type = 'round corner'; + this.type = 'round corner' + (opt_position ? ' ' + opt_position : ''); this.width = this.constants_.CORNER_RADIUS; // The rounded corner extends into the next row by 4 so we only take the // height that is aligned with this row. this.height = this.constants_.NOTCH.height; }; -goog.inherits(Blockly.blockRendering.RoundCorner, Blockly.blockRendering.Measurable); +goog.inherits(Blockly.blockRendering.RoundCorner, + Blockly.blockRendering.Measurable); /** * An object containing information about a spacer between two elements on a diff --git a/core/renderers/measurables/rows.js b/core/renderers/measurables/rows.js index 4ef7dbdd8..808f3b104 100644 --- a/core/renderers/measurables/rows.js +++ b/core/renderers/measurables/rows.js @@ -251,11 +251,9 @@ goog.inherits(Blockly.blockRendering.TopRow, Blockly.blockRendering.Row); Blockly.blockRendering.TopRow.prototype.populate = function(block) { var hasHat = block.hat ? block.hat === 'cap' : Blockly.BlockSvg.START_HAT; var hasPrevious = !!block.previousConnection; - var prevBlock = block.getPreviousBlock(); - var squareCorner = !!block.outputConnection || - hasHat || (prevBlock && prevBlock.getNextBlock() == block); + var leftSquareCorner = this.hasLeftSquareCorner(block); - if (squareCorner) { + if (leftSquareCorner) { this.elements.push(new Blockly.blockRendering.SquareCorner()); } else { this.elements.push(new Blockly.blockRendering.RoundCorner()); @@ -284,6 +282,19 @@ Blockly.blockRendering.TopRow.prototype.populate = function(block) { } }; +/** + * Returns whether or not the top row has a left square corner. + * @param {!Blockly.BlockSvg} block The block whose top row this represents. + * @returns {boolean} Whether or not the top row has a left square corner. + */ +Blockly.blockRendering.TopRow.prototype.hasLeftSquareCorner = function(block) { + var hasHat = block.hat ? block.hat === 'cap' : Blockly.BlockSvg.START_HAT; + var prevBlock = block.getPreviousBlock(); + + return !!block.outputConnection || + hasHat || (prevBlock && prevBlock.getNextBlock() == block); +}; + /** * @override */ @@ -351,17 +362,17 @@ Blockly.blockRendering.BottomRow.prototype.populate = function(block) { block.inputList.length && block.inputList[block.inputList.length - 1].type == Blockly.NEXT_STATEMENT; - // This is the minimum height for the row. If one of its elements has a greater - // height it will be overwritten in the compute pass. + // This is the minimum height for the row. If one of its elements has a + // greater height it will be overwritten in the compute pass. if (followsStatement) { this.minHeight = this.constants_.LARGE_PADDING; } else { this.minHeight = this.constants_.NOTCH.height; } - var squareCorner = !!block.outputConnection || !!block.getNextBlock(); + var leftSquareCorner = this.hasLeftSquareCorner(block); - if (squareCorner) { + if (leftSquareCorner) { this.elements.push(new Blockly.blockRendering.SquareCorner()); } else { this.elements.push(new Blockly.blockRendering.RoundCorner()); @@ -374,6 +385,16 @@ Blockly.blockRendering.BottomRow.prototype.populate = function(block) { } }; +/** + * Returns whether or not the bottom row has a left square corner. + * @param {!Blockly.BlockSvg} block The block whose bottom row this represents. + * @returns {boolean} Whether or not the bottom row has a left square corner. + */ +Blockly.blockRendering.BottomRow.prototype.hasLeftSquareCorner = function( + block) { + return !!block.outputConnection || !!block.getNextBlock(); +}; + /** * @override */ diff --git a/core/renderers/zelos/constants.js b/core/renderers/zelos/constants.js index 711b69a9b..b91483d83 100644 --- a/core/renderers/zelos/constants.js +++ b/core/renderers/zelos/constants.js @@ -38,14 +38,20 @@ goog.require('Blockly.utils.svgPaths'); */ Blockly.zelos.ConstantProvider = function() { Blockly.zelos.ConstantProvider.superClass_.constructor.call(this); + + var GRID_UNIT = 4; - this.CORNER_RADIUS = 4; + this.CORNER_RADIUS = 1 * GRID_UNIT; - this.NOTCH_WIDTH = 36; + this.NOTCH_WIDTH = 9 * GRID_UNIT; - this.NOTCH_HEIGHT = 8; + this.NOTCH_HEIGHT = 2 * GRID_UNIT; - this.NOTCH_OFFSET_LEFT = 12; + this.NOTCH_OFFSET_LEFT = 3 * GRID_UNIT; + + this.MIN_BLOCK_HEIGHT = 12 * GRID_UNIT; + + this.DARK_PATH_OFFSET = 0; }; goog.inherits(Blockly.zelos.ConstantProvider, Blockly.blockRendering.ConstantProvider); @@ -125,31 +131,45 @@ Blockly.zelos.ConstantProvider.prototype.makeNotch = function() { function makeMainPath(dir) { return ( Blockly.utils.svgPaths.curve('c', [ - Blockly.utils.svgPaths.point(dir * curveWidth / 2, 0), - Blockly.utils.svgPaths.point(dir * curveWidth * 3 / 4, quarterHeight / 2), - Blockly.utils.svgPaths.point(dir * curveWidth, quarterHeight) + Blockly.utils.svgPaths.point(dir * curveWidth / 2, + 0), + Blockly.utils.svgPaths.point(dir * curveWidth * 3 / 4, + quarterHeight / 2), + Blockly.utils.svgPaths.point(dir * curveWidth, + quarterHeight) ]) + Blockly.utils.svgPaths.line([ - Blockly.utils.svgPaths.point(dir * curveWidth, halfHeight) + Blockly.utils.svgPaths.point(dir * curveWidth, + halfHeight) ]) + Blockly.utils.svgPaths.curve('c', [ - Blockly.utils.svgPaths.point(dir * curveWidth / 4, quarterHeight / 2), - Blockly.utils.svgPaths.point(dir * curveWidth / 2, quarterHeight), - Blockly.utils.svgPaths.point(dir * curveWidth, quarterHeight) + Blockly.utils.svgPaths.point(dir * curveWidth / 4, + quarterHeight / 2), + Blockly.utils.svgPaths.point(dir * curveWidth / 2, + quarterHeight), + Blockly.utils.svgPaths.point(dir * curveWidth, + quarterHeight) ]) + Blockly.utils.svgPaths.lineOnAxis('h', dir * innerWidth) + Blockly.utils.svgPaths.curve('c', [ - Blockly.utils.svgPaths.point(dir * curveWidth / 2, 0), - Blockly.utils.svgPaths.point(dir * curveWidth * 3 / 4, -(quarterHeight / 2)), - Blockly.utils.svgPaths.point(dir * curveWidth, -quarterHeight) + Blockly.utils.svgPaths.point(dir * curveWidth / 2, + 0), + Blockly.utils.svgPaths.point(dir * curveWidth * 3 / 4, + -(quarterHeight / 2)), + Blockly.utils.svgPaths.point(dir * curveWidth, + -quarterHeight) ]) + Blockly.utils.svgPaths.line([ - Blockly.utils.svgPaths.point(dir * curveWidth, -halfHeight) + Blockly.utils.svgPaths.point(dir * curveWidth, + -halfHeight) ]) + Blockly.utils.svgPaths.curve('c', [ - Blockly.utils.svgPaths.point(dir * curveWidth / 4, -(quarterHeight / 2)), - Blockly.utils.svgPaths.point(dir * curveWidth / 2, -quarterHeight), - Blockly.utils.svgPaths.point(dir * curveWidth, -quarterHeight) + Blockly.utils.svgPaths.point(dir * curveWidth / 4, + -(quarterHeight / 2)), + Blockly.utils.svgPaths.point(dir * curveWidth / 2, + -quarterHeight), + Blockly.utils.svgPaths.point(dir * curveWidth, + -quarterHeight) ]) ); } @@ -165,3 +185,49 @@ Blockly.zelos.ConstantProvider.prototype.makeNotch = function() { pathRight: pathRight }; }; + +/** + * @return {!Object} An object containing sizing and path information about + * outside corners. + * @package + */ +Blockly.zelos.ConstantProvider.prototype.makeOutsideCorners = function() { + var radius = this.CORNER_RADIUS; + /** + * SVG path for drawing the rounded top-left corner. + * @const + */ + var topLeft = + Blockly.utils.svgPaths.moveBy(0, radius) + + Blockly.utils.svgPaths.arc('a', '0 0,1', radius, + Blockly.utils.svgPaths.point(radius, -radius)); + + /** + * SVG path for drawing the rounded top-right corner. + * @const + */ + var topRight = + Blockly.utils.svgPaths.arc('a', '0 0,1', radius, + Blockly.utils.svgPaths.point(radius, radius)); + + /** + * SVG path for drawing the rounded bottom-left corner. + * @const + */ + var bottomLeft = Blockly.utils.svgPaths.arc('a', '0 0,1', radius, + Blockly.utils.svgPaths.point(-radius, -radius)); + + /** + * SVG path for drawing the rounded bottom-right corner. + * @const + */ + var bottomRight = Blockly.utils.svgPaths.arc('a', '0 0,1', radius, + Blockly.utils.svgPaths.point(-radius, radius)); + + return { + topLeft: topLeft, + topRight: topRight, + bottomRight: bottomRight, + bottomLeft: bottomLeft + }; +}; diff --git a/core/renderers/zelos/drawer.js b/core/renderers/zelos/drawer.js index 7bfe4e4ac..c75768aa0 100644 --- a/core/renderers/zelos/drawer.js +++ b/core/renderers/zelos/drawer.js @@ -45,3 +45,63 @@ Blockly.zelos.Drawer = function(block, info) { }; goog.inherits(Blockly.zelos.Drawer, Blockly.blockRendering.Drawer); + +/** + * Add steps for the top corner of the block, taking into account + * details such as hats and rounded corners. + * @protected + */ +Blockly.zelos.Drawer.prototype.drawTop_ = function() { + var topRow = this.info_.topRow; + var elements = topRow.elements; + + this.positionPreviousConnection_(); + this.outlinePath_ += + Blockly.utils.svgPaths.moveBy(topRow.xPos, this.info_.startY); + for (var i = 0, elem; (elem = elements[i]); i++) { + if (elem.type == 'round corner') { + this.outlinePath_ += + this.constants_.OUTSIDE_CORNERS.topLeft; + } else if (elem.type == 'round corner right') { + this.outlinePath_ += + this.constants_.OUTSIDE_CORNERS.topRight; + } else if (elem.type == 'previous connection') { + this.outlinePath_ += elem.shape.pathLeft; + } else if (elem.type == 'hat') { + this.outlinePath_ += this.constants_.START_HAT.path; + } else if (elem.isSpacer()) { + this.outlinePath_ += Blockly.utils.svgPaths.lineOnAxis('h', elem.width); + } + // No branch for a 'square corner', because it's a no-op. + } + this.outlinePath_ += Blockly.utils.svgPaths.lineOnAxis('v', topRow.height); +}; + + +/** + * Add steps for the bottom edge of a block, possibly including a notch + * for the next connection + * @protected + */ +Blockly.zelos.Drawer.prototype.drawBottom_ = function() { + var bottomRow = this.info_.bottomRow; + var elems = bottomRow.elements; + this.positionNextConnection_(); + + this.outlinePath_ += + Blockly.utils.svgPaths.lineOnAxis('v', bottomRow.height - bottomRow.overhangY); + + for (var i = elems.length - 1, elem; (elem = elems[i]); i--) { + if (elem.isNextConnection()) { + this.outlinePath_ += elem.shape.pathRight; + } else if (elem.isSquareCorner()) { + this.outlinePath_ += Blockly.utils.svgPaths.lineOnAxis('H', bottomRow.xPos); + } else if (elem.isRoundedCorner()) { + this.outlinePath_ += this.constants_.OUTSIDE_CORNERS.bottomLeft; + } else if (elem.type == 'round corner right') { + this.outlinePath_ += this.constants_.OUTSIDE_CORNERS.bottomRight; + } else if (elem.isSpacer()) { + this.outlinePath_ += Blockly.utils.svgPaths.lineOnAxis('h', elem.width * -1); + } + } +}; diff --git a/core/renderers/zelos/info.js b/core/renderers/zelos/info.js index 0e0af2d90..3ae1efc8b 100644 --- a/core/renderers/zelos/info.js +++ b/core/renderers/zelos/info.js @@ -46,6 +46,9 @@ goog.require('Blockly.blockRendering.OutputConnection'); goog.require('Blockly.RenderedConnection'); +goog.require('Blockly.zelos.BottomRow'); +goog.require('Blockly.zelos.TopRow'); + /** * An object containing all sizing information needed to draw this block. * @@ -60,6 +63,20 @@ goog.require('Blockly.RenderedConnection'); */ Blockly.zelos.RenderInfo = function(block) { Blockly.zelos.RenderInfo.superClass_.constructor.call(this, block); + + /** + * An object with rendering information about the top row of the block. + * @type {!Blockly.zelos.TopRow} + * @override + */ + this.topRow = new Blockly.zelos.TopRow(); + + /** + * An object with rendering information about the bottom row of the block. + * @type {!Blockly.zelos.BottomRow} + * @override + */ + this.bottomRow = new Blockly.zelos.BottomRow(); }; goog.inherits(Blockly.zelos.RenderInfo, Blockly.blockRendering.RenderInfo); @@ -105,6 +122,10 @@ Blockly.zelos.RenderInfo.prototype.getInRowSpacing_ = function(prev, next) { if (prev.isRoundedCorner()) { return this.constants_.MIN_BLOCK_WIDTH; } + // Between a right rounded corner and the end of the row. + if (prev.type == 'round corner right') { + return this.constants_.NO_PADDING; + } // Between a jagged edge and the end of the row. if (prev.isJaggedEdge()) { return this.constants_.NO_PADDING; @@ -203,3 +224,25 @@ Blockly.zelos.RenderInfo.prototype.getInRowSpacing_ = function(prev, next) { return this.constants_.MEDIUM_PADDING; }; + +/** + * Modify the given row to add the given amount of padding around its fields. + * The exact location of the padding is based on the alignment property of the + * last input in the field. + * @param {Blockly.blockRendering.Row} row The row to add padding to. + * @param {number} missingSpace How much padding to add. + * @protected + */ +Blockly.zelos.RenderInfo.prototype.addAlignmentPadding_ = function(row, + missingSpace) { + var lastSpacer = row.getLastSpacer(); + // Skip the right corner element on the top and bottom row, so we don't have + // any spacing after the right corner element. + if (row.type == 'top row' || row.type == 'bottom row') { + lastSpacer = row.elements[row.elements.length - 3]; + } + if (lastSpacer) { + lastSpacer.width += missingSpace; + row.width += missingSpace; + } +}; diff --git a/core/renderers/zelos/measurables/rows.js b/core/renderers/zelos/measurables/rows.js new file mode 100644 index 000000000..0680d8267 --- /dev/null +++ b/core/renderers/zelos/measurables/rows.js @@ -0,0 +1,131 @@ +/** + * @license + * Visual Blocks Editor + * + * Copyright 2019 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 An object representing a single row on a rendered block and all + * of its subcomponents. + * @author samelh@google.com (Sam El-Husseini) + */ +'use strict'; + +goog.provide('Blockly.zelos.BottomRow'); +goog.provide('Blockly.zelos.TopRow'); + +goog.require('Blockly.blockRendering.BottomRow'); +goog.require('Blockly.blockRendering.TopRow'); + + +/** + * An object containing information about what elements are in the top row of a + * block as well as sizing information for the top row. + * Elements in a top row can consist of corners, hats, spacers, and previous + * connections. + * After this constructor is called, the row will contain all non-spacer + * elements it needs. + * @package + * @constructor + * @extends {Blockly.blockRendering.TopRow} + */ +Blockly.zelos.TopRow = function() { + Blockly.zelos.TopRow.superClass_.constructor.call(this); +}; +goog.inherits(Blockly.zelos.TopRow, Blockly.blockRendering.TopRow); + +/** + * Create all non-spacer elements that belong on the top row. + * @param {!Blockly.BlockSvg} block The block whose top row this represents. + * @package + * @override + */ +Blockly.zelos.TopRow.prototype.populate = function(block) { + Blockly.zelos.TopRow.superClass_.populate.call(this, block); + + var rightSquareCorner = this.hasRightSquareCorner(block); + + if (rightSquareCorner) { + this.elements.push(new Blockly.blockRendering.SquareCorner('right')); + } else { + this.elements.push(new Blockly.blockRendering.RoundCorner('right')); + } +}; + +/** + * Never render a left square corner. Always round. + * @override + */ +Blockly.zelos.TopRow.prototype.hasLeftSquareCorner = function(_block) { + return false; +}; + +/** + * Never render a right square corner. Always round. + * @override + */ +Blockly.zelos.TopRow.prototype.hasRightSquareCorner = function(_block) { + return false; +}; + +/** + * An object containing information about what elements are in the bottom row of + * a block as well as spacing information for the top row. + * Elements in a bottom row can consist of corners, spacers and next + * connections. + * @package + * @constructor + * @extends {Blockly.blockRendering.BottomRow} + */ +Blockly.zelos.BottomRow = function() { + Blockly.zelos.BottomRow.superClass_.constructor.call(this); +}; +goog.inherits(Blockly.zelos.BottomRow, Blockly.blockRendering.BottomRow); + +/** + * Create all non-spacer elements that belong on the bottom row. + * @param {!Blockly.BlockSvg} block The block whose bottom row this represents. + * @package + * @override + */ +Blockly.zelos.BottomRow.prototype.populate = function(block) { + Blockly.zelos.BottomRow.superClass_.populate.call(this, block); + + var rightSquareCorner = this.hasRightSquareCorner(block); + + if (rightSquareCorner) { + this.elements.push(new Blockly.blockRendering.SquareCorner('right')); + } else { + this.elements.push(new Blockly.blockRendering.RoundCorner('right')); + } +}; + +/** + * Never render a left square corner. Always round. + * @override + */ +Blockly.zelos.BottomRow.prototype.hasLeftSquareCorner = function(_block) { + return false; +}; + +/** + * Never render a right square corner. Always round. + * @override + */ +Blockly.zelos.BottomRow.prototype.hasRightSquareCorner = function(_block) { + return false; +};