/** * @license * Copyright 2019 Google LLC * SPDX-License-Identifier: Apache-2.0 */ /** * @fileoverview An object that provides constants for rendering blocks. * @author fenichel@google.com (Rachel Fenichel) */ 'use strict'; goog.provide('Blockly.blockRendering.ConstantProvider'); goog.require('Blockly.constants'); goog.require('Blockly.utils'); goog.require('Blockly.utils.colour'); goog.require('Blockly.utils.dom'); goog.require('Blockly.utils.Svg'); goog.require('Blockly.utils.svgPaths'); goog.require('Blockly.utils.userAgent'); goog.requireType('Blockly.blockRendering.Debug'); goog.requireType('Blockly.RenderedConnection'); goog.requireType('Blockly.Theme'); /** * An object that provides constants for rendering blocks. * @constructor * @package */ Blockly.blockRendering.ConstantProvider = function() { /** * The size of an empty spacer. * @type {number} */ this.NO_PADDING = 0; /** * The size of small padding. * @type {number} */ this.SMALL_PADDING = 3; /** * The size of medium padding. * @type {number} */ this.MEDIUM_PADDING = 5; /** * The size of medium-large padding. * @type {number} */ this.MEDIUM_LARGE_PADDING = 8; /** * The size of large padding. * @type {number} */ this.LARGE_PADDING = 10; /** * Offset from the top of the row for placing fields on inline input rows * and statement input rows. * Matches existing rendering (in 2019). * @type {number} */ this.TALL_INPUT_FIELD_OFFSET_Y = this.MEDIUM_PADDING; /** * The height of the puzzle tab used for input and output connections. * @type {number} */ this.TAB_HEIGHT = 15; /** * The offset from the top of the block at which a puzzle tab is positioned. * @type {number} */ this.TAB_OFFSET_FROM_TOP = 5; /** * Vertical overlap of the puzzle tab, used to make it look more like a puzzle * piece. * @type {number} */ this.TAB_VERTICAL_OVERLAP = 2.5; /** * The width of the puzzle tab used for input and output connections. * @type {number} */ this.TAB_WIDTH = 8; /** * The width of the notch used for previous and next connections. * @type {number} */ this.NOTCH_WIDTH = 15; /** * The height of the notch used for previous and next connections. * @type {number} */ this.NOTCH_HEIGHT = 4; /** * The minimum width of the block. * @type {number} */ this.MIN_BLOCK_WIDTH = 12; this.EMPTY_BLOCK_SPACER_HEIGHT = 16; /** * The minimum height of a dummy input row. * @type {number} */ this.DUMMY_INPUT_MIN_HEIGHT = this.TAB_HEIGHT; /** * The minimum height of a dummy input row in a shadow block. * @type {number} */ this.DUMMY_INPUT_SHADOW_MIN_HEIGHT = this.TAB_HEIGHT; /** * Rounded corner radius. * @type {number} */ this.CORNER_RADIUS = 8; /** * Offset from the left side of a block or the inside of a statement input to * the left side of the notch. * @type {number} */ this.NOTCH_OFFSET_LEFT = 15; /** * Additional offset added to the statement input's width to account for the * notch. * @type {number} */ this.STATEMENT_INPUT_NOTCH_OFFSET = this.NOTCH_OFFSET_LEFT; this.STATEMENT_BOTTOM_SPACER = 0; this.STATEMENT_INPUT_PADDING_LEFT = 20; /** * Vertical padding between consecutive statement inputs. * @type {number} */ this.BETWEEN_STATEMENT_PADDING_Y = 4; /** * The top row's minimum height. * @type {number} */ this.TOP_ROW_MIN_HEIGHT = this.MEDIUM_PADDING; /** * The top row's minimum height if it precedes a statement. * @type {number} */ this.TOP_ROW_PRECEDES_STATEMENT_MIN_HEIGHT = this.LARGE_PADDING; /** * The bottom row's minimum height. * @type {number} */ this.BOTTOM_ROW_MIN_HEIGHT = this.MEDIUM_PADDING; /** * The bottom row's minimum height if it follows a statement input. * @type {number} */ this.BOTTOM_ROW_AFTER_STATEMENT_MIN_HEIGHT = this.LARGE_PADDING; /** * Whether to add a 'hat' on top of all blocks with no previous or output * connections. Can be overridden by 'hat' property on Theme.BlockStyle. * @type {boolean} */ this.ADD_START_HATS = false; /** * Height of the top hat. * @type {number} */ this.START_HAT_HEIGHT = 15; /** * Width of the top hat. * @type {number} */ this.START_HAT_WIDTH = 100; this.SPACER_DEFAULT_HEIGHT = 15; this.MIN_BLOCK_HEIGHT = 24; this.EMPTY_INLINE_INPUT_PADDING = 14.5; /** * The height of an empty inline input. * @type {number} */ this.EMPTY_INLINE_INPUT_HEIGHT = this.TAB_HEIGHT + 11; this.EXTERNAL_VALUE_INPUT_PADDING = 2; /** * The height of an empty statement input. Note that in the old rendering this * varies slightly depending on whether the block has external or inline inputs. * In the new rendering this is consistent. It seems unlikely that the old * behaviour was intentional. * @type {number} */ this.EMPTY_STATEMENT_INPUT_HEIGHT = this.MIN_BLOCK_HEIGHT; this.START_POINT = Blockly.utils.svgPaths.moveBy(0, 0); /** * Height of SVG path for jagged teeth at the end of collapsed blocks. * @type {number} */ this.JAGGED_TEETH_HEIGHT = 12; /** * Width of SVG path for jagged teeth at the end of collapsed blocks. * @type {number} */ this.JAGGED_TEETH_WIDTH = 6; /** * Point size of text. * @type {number} */ this.FIELD_TEXT_FONTSIZE = 11; /** * Text font weight. * @type {string} */ this.FIELD_TEXT_FONTWEIGHT = 'normal'; /** * Text font family. * @type {string} */ this.FIELD_TEXT_FONTFAMILY = 'sans-serif'; /** * Height of text. This constant is dynamically set in ``setFontConstants_`` * to be the height of the text based on the font used. * @type {number} */ this.FIELD_TEXT_HEIGHT = -1; // Dynamically set /** * Text baseline. This constant is dynamically set in ``setFontConstants_`` * to be the baseline of the text based on the font used. * @type {number} */ this.FIELD_TEXT_BASELINE = -1; // Dynamically set /** * A field's border rect corner radius. * @type {number} */ this.FIELD_BORDER_RECT_RADIUS = 4; /** * A field's border rect default height. * @type {number} */ this.FIELD_BORDER_RECT_HEIGHT = 16; /** * A field's border rect X padding. * @type {number} */ this.FIELD_BORDER_RECT_X_PADDING = 5; /** * A field's border rect Y padding. * @type {number} */ this.FIELD_BORDER_RECT_Y_PADDING = 3; /** * The backing colour of a field's border rect. * @type {string} * @package */ this.FIELD_BORDER_RECT_COLOUR = '#fff'; /** * A field's text element's dominant baseline. * @type {boolean} */ this.FIELD_TEXT_BASELINE_CENTER = !Blockly.utils.userAgent.IE && !Blockly.utils.userAgent.EDGE; /** * A dropdown field's border rect height. * @type {number} */ this.FIELD_DROPDOWN_BORDER_RECT_HEIGHT = this.FIELD_BORDER_RECT_HEIGHT; /** * Whether or not a dropdown field should add a border rect when in a shadow * block. * @type {boolean} */ this.FIELD_DROPDOWN_NO_BORDER_RECT_SHADOW = false; /** * Whether or not a dropdown field's div should be coloured to match the * block colours. * @type {boolean} */ this.FIELD_DROPDOWN_COLOURED_DIV = false; /** * Whether or not a dropdown field uses a text or SVG arrow. * @type {boolean} */ this.FIELD_DROPDOWN_SVG_ARROW = false; /** * A dropdown field's SVG arrow padding. * @type {number} */ this.FIELD_DROPDOWN_SVG_ARROW_PADDING = this.FIELD_BORDER_RECT_X_PADDING; /** * A dropdown field's SVG arrow size. * @type {number} */ this.FIELD_DROPDOWN_SVG_ARROW_SIZE = 12; /** * A dropdown field's SVG arrow datauri. * @type {string} */ this.FIELD_DROPDOWN_SVG_ARROW_DATAURI = 'data:image/svg+xml;base64,PHN2ZyBpZD0iTGF5ZXJfMSIgZGF0YS1uYW1lPSJMYXllci' + 'AxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMi43MSIgaG' + 'VpZ2h0PSI4Ljc5IiB2aWV3Qm94PSIwIDAgMTIuNzEgOC43OSI+PHRpdGxlPmRyb3Bkb3duLW' + 'Fycm93PC90aXRsZT48ZyBvcGFjaXR5PSIwLjEiPjxwYXRoIGQ9Ik0xMi43MSwyLjQ0QTIuND' + 'EsMi40MSwwLDAsMSwxMiw0LjE2TDguMDgsOC4wOGEyLjQ1LDIuNDUsMCwwLDEtMy40NSwwTD' + 'AuNzIsNC4xNkEyLjQyLDIuNDIsMCwwLDEsMCwyLjQ0LDIuNDgsMi40OCwwLDAsMSwuNzEuNz' + 'FDMSwwLjQ3LDEuNDMsMCw2LjM2LDBTMTEuNzUsMC40NiwxMiwuNzFBMi40NCwyLjQ0LDAsMC' + 'wxLDEyLjcxLDIuNDRaIiBmaWxsPSIjMjMxZjIwIi8+PC9nPjxwYXRoIGQ9Ik02LjM2LDcuNz' + 'lhMS40MywxLjQzLDAsMCwxLTEtLjQyTDEuNDIsMy40NWExLjQ0LDEuNDQsMCwwLDEsMC0yYz' + 'AuNTYtLjU2LDkuMzEtMC41Niw5Ljg3LDBhMS40NCwxLjQ0LDAsMCwxLDAsMkw3LjM3LDcuMz' + 'dBMS40MywxLjQzLDAsMCwxLDYuMzYsNy43OVoiIGZpbGw9IiNmZmYiLz48L3N2Zz4='; /** * Whether or not to show a box shadow around the widget div. This is only a * feature of full block fields. * @type {boolean} */ this.FIELD_TEXTINPUT_BOX_SHADOW = false; /** * Whether or not the colour field should display its colour value on the * entire block. * @type {boolean} */ this.FIELD_COLOUR_FULL_BLOCK = false; /** * A colour field's default width. * @type {number} */ this.FIELD_COLOUR_DEFAULT_WIDTH = 26; /** * A colour field's default height. * @type {number} */ this.FIELD_COLOUR_DEFAULT_HEIGHT = this.FIELD_BORDER_RECT_HEIGHT; /** * A checkbox field's X offset. * @type {number} */ this.FIELD_CHECKBOX_X_OFFSET = this.FIELD_BORDER_RECT_X_PADDING - 3; /** * A random identifier used to ensure a unique ID is used for each * filter/pattern for the case of multiple Blockly instances on a page. * @type {string} * @package */ this.randomIdentifier = String(Math.random()).substring(2); /** * The ID of the emboss filter, or the empty string if no filter is set. * @type {string} * @package */ this.embossFilterId = ''; /** * The element to use for highlighting, or null if not set. * @type {SVGElement} * @private */ this.embossFilter_ = null; /** * The ID of the disabled pattern, or the empty string if no pattern is set. * @type {string} * @package */ this.disabledPatternId = ''; /** * The element to use for disabled blocks, or null if not set. * @type {SVGElement} * @private */ this.disabledPattern_ = null; /** * The ID of the debug filter, or the empty string if no pattern is set. * @type {string} * @package */ this.debugFilterId = ''; /** * The element to use for a debug highlight, or null if not set. * @type {SVGElement} * @private */ this.debugFilter_ = null; /** * The