From 4eb791bd705387baa36a42df6452e483cfe7f917 Mon Sep 17 00:00:00 2001 From: Sam El-Husseini Date: Thu, 5 Dec 2019 17:51:39 -0800 Subject: [PATCH] [zelos] Add right connection shape element. (#3488) * Add right connection shape element --- blockly_uncompressed.js | 3 +- core/renderers/common/debugger.js | 3 + core/renderers/common/info.js | 3 +- core/renderers/measurables/connections.js | 18 +---- core/renderers/zelos/info.js | 79 +++++++++---------- .../zelos/measurables/row_elements.js | 48 +++++++++++ tests/rendering/zelos/zelos.html | 1 + 7 files changed, 97 insertions(+), 58 deletions(-) create mode 100644 core/renderers/zelos/measurables/row_elements.js diff --git a/blockly_uncompressed.js b/blockly_uncompressed.js index aa1c60289..6ac4ce25a 100644 --- a/blockly_uncompressed.js +++ b/blockly_uncompressed.js @@ -119,8 +119,9 @@ goog.addDependency("../../core/renderers/thrasos/info.js", ['Blockly.thrasos', ' goog.addDependency("../../core/renderers/thrasos/renderer.js", ['Blockly.thrasos.Renderer'], ['Blockly.blockRendering', 'Blockly.blockRendering.Renderer', 'Blockly.thrasos.RenderInfo', 'Blockly.utils.object']); goog.addDependency("../../core/renderers/zelos/constants.js", ['Blockly.zelos.ConstantProvider'], ['Blockly.blockRendering.ConstantProvider', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.svgPaths']); goog.addDependency("../../core/renderers/zelos/drawer.js", ['Blockly.zelos.Drawer'], ['Blockly.blockRendering.ConstantProvider', 'Blockly.blockRendering.Drawer', 'Blockly.blockRendering.Types', 'Blockly.utils.object', 'Blockly.zelos.RenderInfo']); -goog.addDependency("../../core/renderers/zelos/info.js", ['Blockly.zelos', 'Blockly.zelos.RenderInfo'], ['Blockly.blockRendering.BottomRow', 'Blockly.blockRendering.ExternalValueInput', 'Blockly.blockRendering.InlineInput', 'Blockly.blockRendering.InputRow', 'Blockly.blockRendering.Measurable', 'Blockly.blockRendering.NextConnection', 'Blockly.blockRendering.OutputConnection', 'Blockly.blockRendering.PreviousConnection', 'Blockly.blockRendering.RenderInfo', 'Blockly.blockRendering.RoundCorner', 'Blockly.blockRendering.Row', 'Blockly.blockRendering.SquareCorner', 'Blockly.blockRendering.SpacerRow', 'Blockly.blockRendering.StatementInput', 'Blockly.blockRendering.TopRow', 'Blockly.blockRendering.Types', 'Blockly.utils.object', 'Blockly.zelos.AfterStatementSpacerRow', 'Blockly.zelos.BeforeStatementSpacerRow', 'Blockly.zelos.BottomRow', 'Blockly.zelos.TopRow']); +goog.addDependency("../../core/renderers/zelos/info.js", ['Blockly.zelos', 'Blockly.zelos.RenderInfo'], ['Blockly.blockRendering.BottomRow', 'Blockly.blockRendering.ExternalValueInput', 'Blockly.blockRendering.InlineInput', 'Blockly.blockRendering.InputRow', 'Blockly.blockRendering.Measurable', 'Blockly.blockRendering.NextConnection', 'Blockly.blockRendering.OutputConnection', 'Blockly.blockRendering.PreviousConnection', 'Blockly.blockRendering.RenderInfo', 'Blockly.blockRendering.RoundCorner', 'Blockly.blockRendering.Row', 'Blockly.blockRendering.SquareCorner', 'Blockly.blockRendering.SpacerRow', 'Blockly.blockRendering.StatementInput', 'Blockly.blockRendering.TopRow', 'Blockly.blockRendering.Types', 'Blockly.utils.object', 'Blockly.zelos.AfterStatementSpacerRow', 'Blockly.zelos.BeforeStatementSpacerRow', 'Blockly.zelos.BottomRow', 'Blockly.zelos.RightConnectionShape', 'Blockly.zelos.TopRow']); goog.addDependency("../../core/renderers/zelos/marker_svg.js", ['Blockly.zelos.MarkerSvg'], ['Blockly.blockRendering.MarkerSvg']); +goog.addDependency("../../core/renderers/zelos/measurables/row_elements.js", ['Blockly.zelos.RightConnectionShape'], ['Blockly.blockRendering.Measurable', 'Blockly.blockRendering.Types', 'Blockly.utils.object']); goog.addDependency("../../core/renderers/zelos/measurables/rows.js", ['Blockly.zelos.BottomRow', 'Blockly.zelos.TopRow', 'Blockly.zelos.AfterStatementSpacerRow', 'Blockly.zelos.BeforeStatementSpacerRow'], ['Blockly.blockRendering.BottomRow', 'Blockly.blockRendering.TopRow', 'Blockly.blockRendering.SpacerRow', 'Blockly.utils.object']); goog.addDependency("../../core/renderers/zelos/path_object.js", ['Blockly.zelos.PathObject'], ['Blockly.blockRendering.PathObject', 'Blockly.zelos.ConstantProvider', 'Blockly.utils.dom', 'Blockly.utils.object']); goog.addDependency("../../core/renderers/zelos/renderer.js", ['Blockly.zelos.Renderer'], ['Blockly.blockRendering', 'Blockly.blockRendering.Renderer', 'Blockly.utils.object', 'Blockly.zelos.ConstantProvider', 'Blockly.zelos.Drawer', 'Blockly.zelos.PathObject', 'Blockly.zelos.RenderInfo', 'Blockly.zelos.MarkerSvg']); diff --git a/core/renderers/common/debugger.js b/core/renderers/common/debugger.js index fbc876f0d..a429e23ae 100644 --- a/core/renderers/common/debugger.js +++ b/core/renderers/common/debugger.js @@ -364,6 +364,9 @@ Blockly.blockRendering.Debug.prototype.drawDebug = function(block, info) { if (block.outputConnection) { this.drawConnection(block.outputConnection); } + if (info.rightSide) { + this.drawRenderedElem(info.rightSide, info.RTL); + } this.drawBoundingBox(info); }; diff --git a/core/renderers/common/info.js b/core/renderers/common/info.js index 92a896f58..4203d9c92 100644 --- a/core/renderers/common/info.js +++ b/core/renderers/common/info.js @@ -728,7 +728,8 @@ Blockly.blockRendering.RenderInfo.prototype.finalize_ = function() { this.recordElemPositions_(row); } - this.widthWithChildren = widestRowWithConnectedBlocks + this.startX; + this.widthWithChildren = Math.max(this.widthWithChildren, + widestRowWithConnectedBlocks + this.startX); this.height = yCursor; this.startY = this.topRow.capline; diff --git a/core/renderers/measurables/connections.js b/core/renderers/measurables/connections.js index abcc75070..5fb3f1632 100644 --- a/core/renderers/measurables/connections.js +++ b/core/renderers/measurables/connections.js @@ -69,9 +69,9 @@ Blockly.blockRendering.OutputConnection = function(constants, connectionModel) { constants, connectionModel); this.type |= Blockly.blockRendering.Types.OUTPUT_CONNECTION; - this.setShapeDimensions( - !this.isDynamicShape ? this.shape.height : 0, - !this.isDynamicShape ? this.shape.width : 0); + this.height = !this.isDynamicShape ? this.shape.height : 0; + this.width = !this.isDynamicShape ? this.shape.width : 0; + this.startX = this.width; this.connectionOffsetY = this.constants_.TAB_OFFSET_FROM_TOP; }; @@ -79,18 +79,6 @@ Blockly.utils.object.inherits(Blockly.blockRendering.OutputConnection, Blockly.blockRendering.Connection); -/** - * Sets properties that depend on the connection shape dimensions. - * @param {number} height Height of the connection shape. - * @param {number} width Width of the connection shape. - */ -Blockly.blockRendering.OutputConnection.prototype.setShapeDimensions = function( - height, width) { - this.height = height; - this.width = width; - this.startX = this.width; -}; - /** * An object containing information about the space a previous connection takes * up during rendering. diff --git a/core/renderers/zelos/info.js b/core/renderers/zelos/info.js index 3f1abf9ed..465de104f 100644 --- a/core/renderers/zelos/info.js +++ b/core/renderers/zelos/info.js @@ -45,6 +45,7 @@ goog.require('Blockly.utils.object'); goog.require('Blockly.zelos.AfterStatementSpacerRow'); goog.require('Blockly.zelos.BeforeStatementSpacerRow'); goog.require('Blockly.zelos.BottomRow'); +goog.require('Blockly.zelos.RightConnectionShape'); goog.require('Blockly.zelos.TopRow'); @@ -82,6 +83,13 @@ Blockly.zelos.RenderInfo = function(renderer, block) { * @override */ this.isInline = true; + + /** + * An object with rendering information about the right connection shape. + * @type {Blockly.zelos.RightConnectionShape} + */ + this.rightSide = this.outputConnection ? + new Blockly.zelos.RightConnectionShape(this.constants_) : null; }; Blockly.utils.object.inherits(Blockly.zelos.RenderInfo, Blockly.blockRendering.RenderInfo); @@ -109,20 +117,6 @@ Blockly.zelos.RenderInfo.prototype.measure = function() { this.finalize_(); }; -/** - * @override - */ -Blockly.zelos.RenderInfo.prototype.computeBounds_ = function() { - Blockly.zelos.RenderInfo.superClass_.computeBounds_.call(this); - - if (this.outputConnection && this.outputConnection.isDynamicShape) { - // Add right connection width. - var rightConnectionWidth = this.outputConnection.width; - this.width += rightConnectionWidth; - this.widthWithChildren += rightConnectionWidth; - } -}; - /** * @override */ @@ -259,42 +253,45 @@ Blockly.zelos.RenderInfo.prototype.adjustXPosition_ = function() { }; /** - * @override + * Finalize the output connection info. In particular set the height of the + * output connection to match that of the block. For the right side, add a + * right connection shape element and have it match the dimensions of the + * output connection. + * @protected */ -Blockly.zelos.RenderInfo.prototype.finalize_ = function() { - // Performance note: this could be combined with the draw pass, if the time - // that this takes is excessive. But it shouldn't be, because it only - // accesses and sets properties that already exist on the objects. +Blockly.zelos.RenderInfo.prototype.finalizeOutputConnection_ = function() { var yCursor = 0; + // Determine the block height. for (var i = 0, row; (row = this.rows[i]); i++) { row.yPos = yCursor; yCursor += row.height; } - this.height = yCursor; - if (this.outputConnection && this.outputConnection.isDynamicShape) { // Dynamic output connections depend on the height of the block. Adjust the // height of the connection. - this.outputConnection.setShapeDimensions( - this.outputConnection.shape.height(this.height), - this.outputConnection.shape.width(this.height)); + var connectionHeight = this.outputConnection.shape.height(yCursor); + var connectionWidth = this.outputConnection.shape.width(yCursor); - // Recompute the bounds as we now know the output connection dimensions. - this.computeBounds_(); + this.outputConnection.height = connectionHeight; + this.outputConnection.width = connectionWidth; + this.outputConnection.startX = connectionWidth; + + // Adjust right side measurable. + this.rightSide.height = connectionHeight; + this.rightSide.width = connectionWidth; + this.rightSide.centerline = connectionHeight / 2; + this.rightSide.xPos = this.width + connectionWidth; + + this.startX = connectionWidth; + this.width += connectionWidth * 2; + this.widthWithChildren += connectionWidth * 2; } - - var widestRowWithConnectedBlocks = 0; - for (var i = 0, row; (row = this.rows[i]); i++) { - row.xPos = this.startX; - - widestRowWithConnectedBlocks = - Math.max(widestRowWithConnectedBlocks, row.widthWithConnectedBlocks); - this.recordElemPositions_(row); - } - - this.widthWithChildren = Math.max(this.widthWithChildren, - widestRowWithConnectedBlocks + this.startX); - - this.startY = this.topRow.capline; - this.bottomRow.baseline = this.height - this.bottomRow.descenderHeight; +}; + +/** + * @override + */ +Blockly.zelos.RenderInfo.prototype.finalize_ = function() { + this.finalizeOutputConnection_(); + Blockly.zelos.RenderInfo.superClass_.finalize_.call(this); }; diff --git a/core/renderers/zelos/measurables/row_elements.js b/core/renderers/zelos/measurables/row_elements.js new file mode 100644 index 000000000..ba6bb2de0 --- /dev/null +++ b/core/renderers/zelos/measurables/row_elements.js @@ -0,0 +1,48 @@ +/** + * @license + * Copyright 2019 Google LLC + * + * 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 Zelos specific objects representing elements in a row of a + * rendered block. + * @author samelh@google.com (Sam El-Husseini) + */ + +goog.provide('Blockly.zelos.RightConnectionShape'); + +goog.require('Blockly.blockRendering.Measurable'); +goog.require('Blockly.blockRendering.Types'); +goog.require('Blockly.utils.object'); + + +/** + * An object containing information about the space a right connection shape + * takes up during rendering. + * @param {!Blockly.blockRendering.ConstantProvider} constants The rendering + * constants provider. + * @package + * @constructor + * @extends {Blockly.blockRendering.Measurable} + */ +Blockly.zelos.RightConnectionShape = function(constants) { + Blockly.zelos.RightConnectionShape.superClass_.constructor.call(this, constants); + this.type |= Blockly.blockRendering.Types.getType('RIGHT_CONNECTION'); + // Size is dynamic + this.height = 0; + this.width = 0; +}; +Blockly.utils.object.inherits(Blockly.zelos.RightConnectionShape, + Blockly.blockRendering.Measurable); diff --git a/tests/rendering/zelos/zelos.html b/tests/rendering/zelos/zelos.html index 7aa679e2c..a9e93bd81 100644 --- a/tests/rendering/zelos/zelos.html +++ b/tests/rendering/zelos/zelos.html @@ -33,6 +33,7 @@ goog.require('Blockly.blockRendering.Debug'); goog.require('Blockly.zelos.Renderer'); // Blockly.blockRendering.startDebugger(); + var blocklyDiv = document.getElementById('blocklyDiv'); var workspace; window.addEventListener('message', function (msg) {