blockly 7.20211209.2 → 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/blockly.d.ts +18963 -18432
- package/blockly.min.js +852 -844
- package/blockly_compressed.js +669 -664
- package/blockly_compressed.js.map +1 -1
- package/blocks/blocks.js +47 -0
- package/blocks/colour.js +13 -3
- package/blocks/lists.js +22 -13
- package/blocks/logic.js +13 -3
- package/blocks/loops.js +24 -11
- package/blocks/math.js +12 -3
- package/blocks/procedures.js +41 -27
- package/blocks/text.js +22 -13
- package/blocks/variables.js +14 -3
- package/blocks/variables_dynamic.js +13 -3
- package/blocks_compressed.js +146 -141
- package/blocks_compressed.js.map +1 -1
- package/core/block.js +1869 -1814
- package/core/block_drag_surface.js +201 -200
- package/core/block_dragger.js +377 -373
- package/core/block_svg.js +1593 -1479
- package/core/blockly.js +8 -22
- package/core/blocks.js +9 -2
- package/core/browser_events.js +22 -5
- package/core/bubble.js +841 -797
- package/core/bubble_dragger.js +213 -206
- package/core/bump_objects.js +2 -2
- package/core/clipboard.js +9 -9
- package/core/comment.js +353 -332
- package/core/common.js +46 -17
- package/core/component_manager.js +181 -174
- package/core/config.js +87 -0
- package/core/connection.js +595 -584
- package/core/connection_checker.js +242 -244
- package/core/connection_db.js +235 -230
- package/core/contextmenu.js +9 -6
- package/core/contextmenu_items.js +1 -2
- package/core/contextmenu_registry.js +93 -89
- package/core/css.js +474 -474
- package/core/delete_area.js +45 -42
- package/core/drag_target.js +57 -56
- package/core/dropdowndiv.js +153 -163
- package/core/events/events.js +2 -2
- package/core/events/events_abstract.js +89 -77
- package/core/events/events_block_base.js +37 -36
- package/core/events/events_block_change.js +130 -124
- package/core/events/events_block_create.js +73 -71
- package/core/events/events_block_delete.js +84 -82
- package/core/events/events_block_drag.js +50 -49
- package/core/events/events_block_move.js +147 -140
- package/core/events/events_bubble_open.js +51 -50
- package/core/events/events_click.js +48 -44
- package/core/events/events_comment_base.js +72 -69
- package/core/events/events_comment_change.js +63 -61
- package/core/events/events_comment_create.js +44 -42
- package/core/events/events_comment_delete.js +42 -40
- package/core/events/events_comment_move.js +106 -104
- package/core/events/events_marker_move.js +65 -64
- package/core/events/events_selected.js +46 -45
- package/core/events/events_theme_change.js +36 -35
- package/core/events/events_toolbox_item_select.js +46 -45
- package/core/events/events_trashcan_open.js +37 -36
- package/core/events/events_ui.js +47 -46
- package/core/events/events_ui_base.js +30 -29
- package/core/events/events_var_base.js +37 -36
- package/core/events/events_var_create.js +50 -48
- package/core/events/events_var_delete.js +50 -48
- package/core/events/events_var_rename.js +51 -49
- package/core/events/events_viewport.js +66 -65
- package/core/events/utils.js +29 -14
- package/core/events/workspace_events.js +49 -55
- package/core/extensions.js +4 -3
- package/core/field.js +1061 -997
- package/core/field_angle.js +462 -442
- package/core/field_checkbox.js +194 -182
- package/core/field_colour.js +519 -505
- package/core/field_dropdown.js +617 -598
- package/core/field_image.js +229 -220
- package/core/field_label.js +102 -91
- package/core/field_label_serializable.js +42 -41
- package/core/field_multilineinput.js +372 -358
- package/core/field_number.js +272 -253
- package/core/field_textinput.js +499 -467
- package/core/field_variable.js +458 -420
- package/core/flyout_base.js +1005 -952
- package/core/flyout_button.js +277 -260
- package/core/flyout_horizontal.js +304 -302
- package/core/flyout_metrics_manager.js +64 -64
- package/core/flyout_vertical.js +306 -300
- package/core/generator.js +459 -446
- package/core/gesture.js +829 -813
- package/core/grid.js +166 -163
- package/core/icon.js +168 -159
- package/core/inject.js +7 -5
- package/core/input.js +257 -248
- package/core/insertion_marker_manager.js +655 -624
- package/core/internal_constants.js +0 -129
- package/core/keyboard_nav/ast_node.js +605 -596
- package/core/keyboard_nav/basic_cursor.js +166 -165
- package/core/keyboard_nav/cursor.js +99 -97
- package/core/keyboard_nav/marker.js +83 -79
- package/core/keyboard_nav/tab_navigate_cursor.js +18 -23
- package/core/marker_manager.js +153 -141
- package/core/menu.js +377 -372
- package/core/menuitem.js +223 -217
- package/core/metrics_manager.js +403 -390
- package/core/mutator.js +468 -437
- package/core/names.js +229 -188
- package/core/options.js +290 -284
- package/core/procedures.js +29 -17
- package/core/registry.js +19 -16
- package/core/rendered_connection.js +482 -463
- package/core/renderers/common/block_rendering.js +9 -3
- package/core/renderers/common/constants.js +1119 -1112
- package/core/renderers/common/debug.js +14 -0
- package/core/renderers/common/debugger.js +338 -316
- package/core/renderers/common/drawer.js +380 -370
- package/core/renderers/common/i_path_object.js +2 -2
- package/core/renderers/common/info.js +626 -618
- package/core/renderers/common/marker_svg.js +579 -541
- package/core/renderers/common/path_object.js +203 -200
- package/core/renderers/common/renderer.js +220 -218
- package/core/renderers/geras/constants.js +36 -36
- package/core/renderers/geras/drawer.js +155 -147
- package/core/renderers/geras/highlight_constants.js +244 -238
- package/core/renderers/geras/highlighter.js +231 -179
- package/core/renderers/geras/info.js +392 -369
- package/core/renderers/geras/measurables/inline_input.js +25 -19
- package/core/renderers/geras/measurables/statement_input.js +23 -17
- package/core/renderers/geras/path_object.js +106 -121
- package/core/renderers/geras/renderer.js +96 -98
- package/core/renderers/measurables/base.js +30 -18
- package/core/renderers/measurables/bottom_row.js +83 -80
- package/core/renderers/measurables/connection.js +22 -15
- package/core/renderers/measurables/external_value_input.js +35 -22
- package/core/renderers/measurables/field.js +35 -20
- package/core/renderers/measurables/hat.js +18 -13
- package/core/renderers/measurables/icon.js +24 -17
- package/core/renderers/measurables/in_row_spacer.js +15 -13
- package/core/renderers/measurables/inline_input.js +43 -33
- package/core/renderers/measurables/input_connection.js +41 -28
- package/core/renderers/measurables/input_row.js +50 -44
- package/core/renderers/measurables/jagged_edge.js +14 -12
- package/core/renderers/measurables/next_connection.js +16 -14
- package/core/renderers/measurables/output_connection.js +26 -20
- package/core/renderers/measurables/previous_connection.js +16 -15
- package/core/renderers/measurables/round_corner.js +20 -18
- package/core/renderers/measurables/row.js +184 -168
- package/core/renderers/measurables/spacer_row.js +38 -23
- package/core/renderers/measurables/square_corner.js +18 -16
- package/core/renderers/measurables/statement_input.js +23 -20
- package/core/renderers/measurables/top_row.js +88 -85
- package/core/renderers/minimalist/constants.js +8 -7
- package/core/renderers/minimalist/drawer.js +11 -10
- package/core/renderers/minimalist/info.js +18 -18
- package/core/renderers/minimalist/renderer.js +40 -39
- package/core/renderers/thrasos/info.js +258 -248
- package/core/renderers/thrasos/renderer.js +20 -20
- package/core/renderers/zelos/constants.js +898 -873
- package/core/renderers/zelos/drawer.js +186 -169
- package/core/renderers/zelos/info.js +502 -479
- package/core/renderers/zelos/marker_svg.js +129 -115
- package/core/renderers/zelos/measurables/bottom_row.js +31 -30
- package/core/renderers/zelos/measurables/inputs.js +22 -21
- package/core/renderers/zelos/measurables/row_elements.js +14 -13
- package/core/renderers/zelos/measurables/top_row.js +34 -33
- package/core/renderers/zelos/path_object.js +181 -180
- package/core/renderers/zelos/renderer.js +91 -92
- package/core/scrollbar.js +759 -713
- package/core/scrollbar_pair.js +250 -245
- package/core/serialization/blocks.js +19 -9
- package/core/serialization/workspaces.js +3 -2
- package/core/shortcut_registry.js +286 -277
- package/core/sprites.js +31 -0
- package/core/theme.js +135 -141
- package/core/theme_manager.js +147 -143
- package/core/toolbox/category.js +602 -576
- package/core/toolbox/collapsible_category.js +226 -227
- package/core/toolbox/separator.js +70 -61
- package/core/toolbox/toolbox.js +934 -927
- package/core/toolbox/toolbox_item.js +115 -99
- package/core/tooltip.js +108 -35
- package/core/touch.js +8 -3
- package/core/touch_gesture.js +254 -251
- package/core/trashcan.js +606 -595
- package/core/utils/coordinate.js +97 -95
- package/core/utils/dom.js +2 -2
- package/core/utils/global.js +2 -0
- package/core/utils/rect.js +41 -37
- package/core/utils/sentinel.js +25 -0
- package/core/utils/size.js +30 -27
- package/core/utils/svg.js +18 -16
- package/core/variable_map.js +325 -341
- package/core/variable_model.js +55 -54
- package/core/variables.js +9 -2
- package/core/variables_dynamic.js +3 -1
- package/core/warning.js +126 -120
- package/core/widgetdiv.js +4 -4
- package/core/workspace.js +685 -664
- package/core/workspace_audio.js +124 -118
- package/core/workspace_comment.js +308 -298
- package/core/workspace_comment_svg.js +1029 -951
- package/core/workspace_drag_surface_svg.js +147 -140
- package/core/workspace_dragger.js +70 -71
- package/core/workspace_svg.js +2322 -2297
- package/core/xml.js +30 -20
- package/core/zoom_controls.js +431 -439
- package/dart_compressed.js +40 -43
- package/dart_compressed.js.map +1 -1
- package/generators/dart/colour.js +56 -64
- package/generators/dart/lists.js +61 -50
- package/generators/dart/math.js +160 -148
- package/generators/dart/text.js +83 -61
- package/generators/javascript/colour.js +37 -34
- package/generators/javascript/lists.js +50 -43
- package/generators/javascript/math.js +123 -139
- package/generators/javascript/text.js +67 -81
- package/generators/lua/colour.js +25 -23
- package/generators/lua/lists.js +97 -69
- package/generators/lua/logic.js +1 -2
- package/generators/lua/math.js +182 -144
- package/generators/lua/text.js +116 -99
- package/generators/php/colour.js +38 -32
- package/generators/php/lists.js +109 -89
- package/generators/php/math.js +90 -81
- package/generators/php/text.js +63 -61
- package/generators/python/colour.js +18 -18
- package/generators/python/lists.js +38 -30
- package/generators/python/loops.js +12 -8
- package/generators/python/math.js +104 -106
- package/generators/python/text.js +34 -30
- package/javascript_compressed.js +37 -39
- package/javascript_compressed.js.map +1 -1
- package/lua_compressed.js +39 -42
- package/lua_compressed.js.map +1 -1
- package/msg/az.js +2 -2
- package/msg/be.js +4 -4
- package/msg/cs.js +15 -15
- package/msg/de.js +1 -1
- package/msg/diq.js +1 -1
- package/msg/eo.js +1 -1
- package/msg/es.js +1 -1
- package/msg/fa.js +1 -1
- package/msg/fr.js +4 -4
- package/msg/he.js +1 -1
- package/msg/hr.js +2 -2
- package/msg/hy.js +2 -2
- package/msg/id.js +12 -12
- package/msg/inh.js +14 -14
- package/msg/ja.js +7 -7
- package/msg/lv.js +29 -29
- package/msg/pa.js +3 -3
- package/msg/smn.js +436 -0
- package/msg/te.js +1 -1
- package/msg/yue.js +1 -1
- package/msg/zh-hans.js +3 -3
- package/msg/zh-hant.js +3 -3
- package/package.json +7 -6
- package/php_compressed.js +38 -42
- package/php_compressed.js.map +1 -1
- package/python_compressed.js +26 -25
- package/python_compressed.js.map +1 -1
- package/blocks/all.js +0 -23
|
@@ -17,15 +17,18 @@
|
|
|
17
17
|
goog.module('Blockly.zelos.RenderInfo');
|
|
18
18
|
|
|
19
19
|
const {Align} = goog.require('Blockly.Input');
|
|
20
|
-
const object = goog.require('Blockly.utils.object');
|
|
21
20
|
/* eslint-disable-next-line no-unused-vars */
|
|
22
21
|
const {BlockSvg} = goog.requireType('Blockly.BlockSvg');
|
|
23
22
|
const {BottomRow} = goog.require('Blockly.zelos.BottomRow');
|
|
24
23
|
/* eslint-disable-next-line no-unused-vars */
|
|
25
24
|
const {ConstantProvider} = goog.requireType('Blockly.zelos.ConstantProvider');
|
|
25
|
+
const {Field} = goog.require('Blockly.blockRendering.Field');
|
|
26
26
|
const {FieldImage} = goog.require('Blockly.FieldImage');
|
|
27
27
|
const {FieldLabel} = goog.require('Blockly.FieldLabel');
|
|
28
28
|
const {FieldTextInput} = goog.require('Blockly.FieldTextInput');
|
|
29
|
+
/* eslint-disable-next-line no-unused-vars */
|
|
30
|
+
const {Input} = goog.requireType('Blockly.Input');
|
|
31
|
+
const {InputConnection} = goog.require('Blockly.blockRendering.InputConnection');
|
|
29
32
|
const {InRowSpacer} = goog.require('Blockly.blockRendering.InRowSpacer');
|
|
30
33
|
/* eslint-disable-next-line no-unused-vars */
|
|
31
34
|
const {Measurable} = goog.requireType('Blockly.blockRendering.Measurable');
|
|
@@ -33,6 +36,10 @@ const {RenderInfo: BaseRenderInfo} = goog.require('Blockly.blockRendering.Render
|
|
|
33
36
|
/* eslint-disable-next-line no-unused-vars */
|
|
34
37
|
const {Renderer} = goog.requireType('Blockly.zelos.Renderer');
|
|
35
38
|
const {RightConnectionShape} = goog.require('Blockly.zelos.RightConnectionShape');
|
|
39
|
+
/* eslint-disable-next-line no-unused-vars */
|
|
40
|
+
const {Row} = goog.require('Blockly.blockRendering.Row');
|
|
41
|
+
/* eslint-disable-next-line no-unused-vars */
|
|
42
|
+
const {SpacerRow} = goog.requireType('Blockly.blockRendering.SpacerRow');
|
|
36
43
|
const {StatementInput} = goog.require('Blockly.zelos.StatementInput');
|
|
37
44
|
const {TopRow} = goog.require('Blockly.zelos.TopRow');
|
|
38
45
|
const {Types} = goog.require('Blockly.blockRendering.Types');
|
|
@@ -45,557 +52,573 @@ const {inputTypes} = goog.require('Blockly.inputTypes');
|
|
|
45
52
|
* This measure pass does not propagate changes to the block (although fields
|
|
46
53
|
* may choose to rerender when getSize() is called). However, calling it
|
|
47
54
|
* repeatedly may be expensive.
|
|
48
|
-
*
|
|
49
|
-
* @param {!Renderer} renderer The renderer in use.
|
|
50
|
-
* @param {!BlockSvg} block The block to measure.
|
|
51
|
-
* @constructor
|
|
52
|
-
* @package
|
|
53
55
|
* @extends {BaseRenderInfo}
|
|
54
56
|
* @alias Blockly.zelos.RenderInfo
|
|
55
57
|
*/
|
|
56
|
-
|
|
57
|
-
RenderInfo.superClass_.constructor.call(this, renderer, block);
|
|
58
|
-
|
|
58
|
+
class RenderInfo extends BaseRenderInfo {
|
|
59
59
|
/**
|
|
60
|
-
*
|
|
61
|
-
* @
|
|
62
|
-
* @
|
|
60
|
+
* @param {!Renderer} renderer The renderer in use.
|
|
61
|
+
* @param {!BlockSvg} block The block to measure.
|
|
62
|
+
* @package
|
|
63
63
|
*/
|
|
64
|
-
|
|
64
|
+
constructor(renderer, block) {
|
|
65
|
+
super(renderer, block);
|
|
66
|
+
|
|
67
|
+
/** @type {!ConstantProvider} */
|
|
68
|
+
this.constants_;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* An object with rendering information about the top row of the block.
|
|
72
|
+
* @type {!TopRow}
|
|
73
|
+
* @override
|
|
74
|
+
*/
|
|
75
|
+
this.topRow = new TopRow(this.constants_);
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* An object with rendering information about the bottom row of the block.
|
|
79
|
+
* @type {!BottomRow}
|
|
80
|
+
* @override
|
|
81
|
+
*/
|
|
82
|
+
this.bottomRow = new BottomRow(this.constants_);
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* @override
|
|
86
|
+
*/
|
|
87
|
+
this.isInline = true;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Whether the block should be rendered as a multi-line block, either
|
|
91
|
+
* because it's not inline or because it has been collapsed.
|
|
92
|
+
* @type {boolean}
|
|
93
|
+
*/
|
|
94
|
+
this.isMultiRow = !block.getInputsInline() || block.isCollapsed();
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Whether or not the block has a statement input in one of its rows.
|
|
98
|
+
* @type {boolean}
|
|
99
|
+
*/
|
|
100
|
+
this.hasStatementInput = block.statementInputCount > 0;
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* An object with rendering information about the right connection shape.
|
|
104
|
+
* @type {RightConnectionShape}
|
|
105
|
+
*/
|
|
106
|
+
this.rightSide = this.outputConnection ?
|
|
107
|
+
new RightConnectionShape(this.constants_) :
|
|
108
|
+
null;
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* A map of rows to right aligned dummy inputs within those rows. Used to
|
|
112
|
+
* add padding between left and right aligned inputs.
|
|
113
|
+
* @type {!WeakMap<!Row, !Input>}
|
|
114
|
+
* @private
|
|
115
|
+
*/
|
|
116
|
+
this.rightAlignedDummyInputs_ = new WeakMap();
|
|
117
|
+
}
|
|
65
118
|
|
|
66
119
|
/**
|
|
67
|
-
*
|
|
68
|
-
* @
|
|
69
|
-
* @
|
|
120
|
+
* Get the block renderer in use.
|
|
121
|
+
* @return {!Renderer} The block renderer in use.
|
|
122
|
+
* @package
|
|
70
123
|
*/
|
|
71
|
-
|
|
124
|
+
getRenderer() {
|
|
125
|
+
return /** @type {!Renderer} */ (this.renderer_);
|
|
126
|
+
}
|
|
72
127
|
|
|
73
128
|
/**
|
|
74
129
|
* @override
|
|
75
130
|
*/
|
|
76
|
-
|
|
131
|
+
measure() {
|
|
132
|
+
// Modifying parent measure method to add `adjustXPosition_`.
|
|
133
|
+
this.createRows_();
|
|
134
|
+
this.addElemSpacing_();
|
|
135
|
+
this.addRowSpacing_();
|
|
136
|
+
this.adjustXPosition_();
|
|
137
|
+
this.computeBounds_();
|
|
138
|
+
this.alignRowElements_();
|
|
139
|
+
this.finalize_();
|
|
140
|
+
}
|
|
77
141
|
|
|
78
142
|
/**
|
|
79
|
-
*
|
|
80
|
-
* it's not inline or because it has been collapsed.
|
|
81
|
-
* @type {boolean}
|
|
143
|
+
* @override
|
|
82
144
|
*/
|
|
83
|
-
|
|
145
|
+
shouldStartNewRow_(input, lastInput) {
|
|
146
|
+
// If this is the first input, just add to the existing row.
|
|
147
|
+
// That row is either empty or has some icons in it.
|
|
148
|
+
if (!lastInput) {
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
// A statement input or an input following one always gets a new row.
|
|
152
|
+
if (input.type === inputTypes.STATEMENT ||
|
|
153
|
+
lastInput.type === inputTypes.STATEMENT) {
|
|
154
|
+
return true;
|
|
155
|
+
}
|
|
156
|
+
// Value and dummy inputs get new row if inputs are not inlined.
|
|
157
|
+
if (input.type === inputTypes.VALUE || input.type === inputTypes.DUMMY) {
|
|
158
|
+
return !this.isInline || this.isMultiRow;
|
|
159
|
+
}
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
84
162
|
|
|
85
163
|
/**
|
|
86
|
-
*
|
|
87
|
-
* @type {boolean}
|
|
164
|
+
* @override
|
|
88
165
|
*/
|
|
89
|
-
|
|
166
|
+
getDesiredRowWidth_(row) {
|
|
167
|
+
if (row.hasStatement) {
|
|
168
|
+
const rightCornerWidth = this.constants_.INSIDE_CORNERS.rightWidth || 0;
|
|
169
|
+
return this.width - this.startX - rightCornerWidth;
|
|
170
|
+
}
|
|
171
|
+
return super.getDesiredRowWidth_(row);
|
|
172
|
+
}
|
|
90
173
|
|
|
91
174
|
/**
|
|
92
|
-
*
|
|
93
|
-
* @type {RightConnectionShape}
|
|
175
|
+
* @override
|
|
94
176
|
*/
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
* @package
|
|
104
|
-
*/
|
|
105
|
-
RenderInfo.prototype.getRenderer = function() {
|
|
106
|
-
return /** @type {!Renderer} */ (this.renderer_);
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* @override
|
|
111
|
-
*/
|
|
112
|
-
RenderInfo.prototype.measure = function() {
|
|
113
|
-
// Modifying parent measure method to add `adjustXPosition_`.
|
|
114
|
-
this.createRows_();
|
|
115
|
-
this.addElemSpacing_();
|
|
116
|
-
this.addRowSpacing_();
|
|
117
|
-
this.adjustXPosition_();
|
|
118
|
-
this.computeBounds_();
|
|
119
|
-
this.alignRowElements_();
|
|
120
|
-
this.finalize_();
|
|
121
|
-
};
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* @override
|
|
125
|
-
*/
|
|
126
|
-
RenderInfo.prototype.shouldStartNewRow_ = function(input, lastInput) {
|
|
127
|
-
// If this is the first input, just add to the existing row.
|
|
128
|
-
// That row is either empty or has some icons in it.
|
|
129
|
-
if (!lastInput) {
|
|
130
|
-
return false;
|
|
131
|
-
}
|
|
132
|
-
// A statement input or an input following one always gets a new row.
|
|
133
|
-
if (input.type === inputTypes.STATEMENT ||
|
|
134
|
-
lastInput.type === inputTypes.STATEMENT) {
|
|
135
|
-
return true;
|
|
136
|
-
}
|
|
137
|
-
// Value and dummy inputs get new row if inputs are not inlined.
|
|
138
|
-
if (input.type === inputTypes.VALUE || input.type === inputTypes.DUMMY) {
|
|
139
|
-
return !this.isInline || this.isMultiRow;
|
|
140
|
-
}
|
|
141
|
-
return false;
|
|
142
|
-
};
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* @override
|
|
147
|
-
*/
|
|
148
|
-
RenderInfo.prototype.getDesiredRowWidth_ = function(row) {
|
|
149
|
-
if (row.hasStatement) {
|
|
150
|
-
const rightCornerWidth = this.constants_.INSIDE_CORNERS.rightWidth || 0;
|
|
151
|
-
return this.width - this.startX - rightCornerWidth;
|
|
152
|
-
}
|
|
153
|
-
return RenderInfo.superClass_.getDesiredRowWidth_.call(this, row);
|
|
154
|
-
};
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* @override
|
|
158
|
-
*/
|
|
159
|
-
RenderInfo.prototype.getInRowSpacing_ = function(prev, next) {
|
|
160
|
-
if (!prev || !next) {
|
|
161
|
-
// No need for padding at the beginning or end of the row if the
|
|
162
|
-
// output shape is dynamic.
|
|
163
|
-
if (this.outputConnection && this.outputConnection.isDynamicShape &&
|
|
164
|
-
!this.hasStatementInput && !this.bottomRow.hasNextConnection) {
|
|
165
|
-
return this.constants_.NO_PADDING;
|
|
177
|
+
getInRowSpacing_(prev, next) {
|
|
178
|
+
if (!prev || !next) {
|
|
179
|
+
// No need for padding at the beginning or end of the row if the
|
|
180
|
+
// output shape is dynamic.
|
|
181
|
+
if (this.outputConnection && this.outputConnection.isDynamicShape &&
|
|
182
|
+
!this.hasStatementInput && !this.bottomRow.hasNextConnection) {
|
|
183
|
+
return this.constants_.NO_PADDING;
|
|
184
|
+
}
|
|
166
185
|
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
186
|
+
if (!prev) {
|
|
187
|
+
// Statement input padding.
|
|
188
|
+
if (next && Types.isStatementInput(next)) {
|
|
189
|
+
return this.constants_.STATEMENT_INPUT_PADDING_LEFT;
|
|
190
|
+
}
|
|
172
191
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
192
|
+
// Spacing between a rounded corner and a previous or next connection.
|
|
193
|
+
if (prev && Types.isLeftRoundedCorner(prev) && next) {
|
|
194
|
+
if (Types.isPreviousConnection(next) || Types.isNextConnection(next)) {
|
|
195
|
+
return next.notchOffset - this.constants_.CORNER_RADIUS;
|
|
196
|
+
}
|
|
178
197
|
}
|
|
198
|
+
// Spacing between a square corner and a hat.
|
|
199
|
+
if (prev && Types.isLeftSquareCorner(prev) && next && Types.isHat(next)) {
|
|
200
|
+
return this.constants_.NO_PADDING;
|
|
201
|
+
}
|
|
202
|
+
return this.constants_.MEDIUM_PADDING;
|
|
179
203
|
}
|
|
180
|
-
// Spacing between a square corner and a hat.
|
|
181
|
-
if (prev && Types.isLeftSquareCorner(prev) && next && Types.isHat(next)) {
|
|
182
|
-
return this.constants_.NO_PADDING;
|
|
183
|
-
}
|
|
184
|
-
return this.constants_.MEDIUM_PADDING;
|
|
185
|
-
};
|
|
186
204
|
|
|
187
|
-
/**
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
}
|
|
195
|
-
const followsStatement = Types.isInputRow(prev) && prev.hasStatement;
|
|
196
|
-
const precedesStatement = Types.isInputRow(next) && next.hasStatement;
|
|
197
|
-
if (precedesStatement || followsStatement) {
|
|
198
|
-
const cornerHeight = this.constants_.INSIDE_CORNERS.rightHeight || 0;
|
|
199
|
-
const height = Math.max(this.constants_.NOTCH_HEIGHT, cornerHeight);
|
|
200
|
-
return precedesStatement && followsStatement ?
|
|
201
|
-
Math.max(height, this.constants_.DUMMY_INPUT_MIN_HEIGHT) :
|
|
202
|
-
height;
|
|
203
|
-
}
|
|
204
|
-
// Top and bottom rows act as a spacer so we don't need any extra padding.
|
|
205
|
-
if (Types.isTopRow(prev)) {
|
|
206
|
-
if (!prev.hasPreviousConnection &&
|
|
207
|
-
(!this.outputConnection || this.hasStatementInput)) {
|
|
208
|
-
return Math.abs(
|
|
209
|
-
this.constants_.NOTCH_HEIGHT - this.constants_.CORNER_RADIUS);
|
|
205
|
+
/**
|
|
206
|
+
* @override
|
|
207
|
+
*/
|
|
208
|
+
getSpacerRowHeight_(prev, next) {
|
|
209
|
+
// If we have an empty block add a spacer to increase the height.
|
|
210
|
+
if (Types.isTopRow(prev) && Types.isBottomRow(next)) {
|
|
211
|
+
return this.constants_.EMPTY_BLOCK_SPACER_HEIGHT;
|
|
210
212
|
}
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
const
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
this.constants_.CORNER_RADIUS)) -
|
|
220
|
-
this.constants_.CORNER_RADIUS;
|
|
221
|
-
return topHeight;
|
|
222
|
-
} else if (!next.hasNextConnection && this.hasStatementInput) {
|
|
223
|
-
return Math.abs(
|
|
224
|
-
this.constants_.NOTCH_HEIGHT - this.constants_.CORNER_RADIUS);
|
|
213
|
+
const followsStatement = Types.isInputRow(prev) && prev.hasStatement;
|
|
214
|
+
const precedesStatement = Types.isInputRow(next) && next.hasStatement;
|
|
215
|
+
if (precedesStatement || followsStatement) {
|
|
216
|
+
const cornerHeight = this.constants_.INSIDE_CORNERS.rightHeight || 0;
|
|
217
|
+
const height = Math.max(this.constants_.NOTCH_HEIGHT, cornerHeight);
|
|
218
|
+
return precedesStatement && followsStatement ?
|
|
219
|
+
Math.max(height, this.constants_.DUMMY_INPUT_MIN_HEIGHT) :
|
|
220
|
+
height;
|
|
225
221
|
}
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
222
|
+
// Top and bottom rows act as a spacer so we don't need any extra padding.
|
|
223
|
+
if (Types.isTopRow(prev)) {
|
|
224
|
+
const topRow = /** @type {!TopRow} */ (prev);
|
|
225
|
+
if (!topRow.hasPreviousConnection &&
|
|
226
|
+
(!this.outputConnection || this.hasStatementInput)) {
|
|
227
|
+
return Math.abs(
|
|
228
|
+
this.constants_.NOTCH_HEIGHT - this.constants_.CORNER_RADIUS);
|
|
229
|
+
}
|
|
230
|
+
return this.constants_.NO_PADDING;
|
|
231
|
+
}
|
|
232
|
+
if (Types.isBottomRow(next)) {
|
|
233
|
+
const bottomRow = /** @type {!BottomRow} */ (next);
|
|
234
|
+
if (!this.outputConnection) {
|
|
235
|
+
const topHeight = Math.max(
|
|
236
|
+
this.topRow.minHeight,
|
|
237
|
+
Math.max(
|
|
238
|
+
this.constants_.NOTCH_HEIGHT,
|
|
239
|
+
this.constants_.CORNER_RADIUS)) -
|
|
240
|
+
this.constants_.CORNER_RADIUS;
|
|
241
|
+
return topHeight;
|
|
242
|
+
} else if (!bottomRow.hasNextConnection && this.hasStatementInput) {
|
|
243
|
+
return Math.abs(
|
|
244
|
+
this.constants_.NOTCH_HEIGHT - this.constants_.CORNER_RADIUS);
|
|
245
|
+
}
|
|
246
|
+
return this.constants_.NO_PADDING;
|
|
247
|
+
}
|
|
248
|
+
return this.constants_.MEDIUM_PADDING;
|
|
239
249
|
}
|
|
240
|
-
return width;
|
|
241
|
-
};
|
|
242
250
|
|
|
243
|
-
/**
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
if (Types.isInlineInput(elem)) {
|
|
252
|
-
const connectedBlock = elem.connectedBlock;
|
|
253
|
-
if (connectedBlock && connectedBlock.outputConnection &&
|
|
254
|
-
connectedBlock.nextConnection) {
|
|
255
|
-
return row.yPos + connectedBlock.height / 2;
|
|
251
|
+
/**
|
|
252
|
+
* @override
|
|
253
|
+
*/
|
|
254
|
+
getSpacerRowWidth_(prev, next) {
|
|
255
|
+
const width = this.width - this.startX;
|
|
256
|
+
if ((Types.isInputRow(prev) && prev.hasStatement) ||
|
|
257
|
+
(Types.isInputRow(next) && next.hasStatement)) {
|
|
258
|
+
return Math.max(width, this.constants_.STATEMENT_INPUT_SPACER_MIN_WIDTH);
|
|
256
259
|
}
|
|
260
|
+
return width;
|
|
257
261
|
}
|
|
258
|
-
return RenderInfo.superClass_.getElemCenterline_.call(this, row, elem);
|
|
259
|
-
};
|
|
260
262
|
|
|
261
|
-
/**
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
if (input.type === inputTypes.DUMMY && activeRow.hasDummyInput &&
|
|
269
|
-
activeRow.align === Align.LEFT && input.align === Align.RIGHT) {
|
|
270
|
-
activeRow.rightAlignedDummyInput = input;
|
|
271
|
-
} else if (input.type === inputTypes.STATEMENT) {
|
|
272
|
-
// Handle statements without next connections correctly.
|
|
273
|
-
activeRow.elements.push(new StatementInput(this.constants_, input));
|
|
274
|
-
activeRow.hasStatement = true;
|
|
275
|
-
|
|
276
|
-
if (activeRow.align === null) {
|
|
277
|
-
activeRow.align = input.align;
|
|
263
|
+
/**
|
|
264
|
+
* @override
|
|
265
|
+
*/
|
|
266
|
+
getElemCenterline_(row, elem) {
|
|
267
|
+
if (row.hasStatement && !Types.isSpacer(elem) &&
|
|
268
|
+
!Types.isStatementInput(elem)) {
|
|
269
|
+
return row.yPos + this.constants_.EMPTY_STATEMENT_INPUT_HEIGHT / 2;
|
|
278
270
|
}
|
|
279
|
-
|
|
271
|
+
if (Types.isInlineInput(elem) && elem instanceof InputConnection) {
|
|
272
|
+
const connectedBlock = elem.connectedBlock;
|
|
273
|
+
if (connectedBlock && connectedBlock.outputConnection &&
|
|
274
|
+
connectedBlock.nextConnection) {
|
|
275
|
+
return row.yPos + connectedBlock.height / 2;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
return super.getElemCenterline_(row, elem);
|
|
280
279
|
}
|
|
281
|
-
RenderInfo.superClass_.addInput_.call(this, input, activeRow);
|
|
282
|
-
};
|
|
283
280
|
|
|
284
|
-
/**
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
281
|
+
/**
|
|
282
|
+
* @override
|
|
283
|
+
*/
|
|
284
|
+
addInput_(input, activeRow) {
|
|
285
|
+
// If we have two dummy inputs on the same row, one aligned left and the
|
|
286
|
+
// other right, keep track of the right aligned dummy input so we can add
|
|
287
|
+
// padding later.
|
|
288
|
+
if (input.type === inputTypes.DUMMY && activeRow.hasDummyInput &&
|
|
289
|
+
activeRow.align === Align.LEFT && input.align === Align.RIGHT) {
|
|
290
|
+
this.rightAlignedDummyInputs_.set(activeRow, input);
|
|
291
|
+
} else if (input.type === inputTypes.STATEMENT) {
|
|
292
|
+
// Handle statements without next connections correctly.
|
|
293
|
+
activeRow.elements.push(new StatementInput(this.constants_, input));
|
|
294
|
+
activeRow.hasStatement = true;
|
|
295
|
+
|
|
296
|
+
if (activeRow.align === null) {
|
|
297
|
+
activeRow.align = input.align;
|
|
298
298
|
}
|
|
299
|
-
}
|
|
300
|
-
if (alignmentDivider) {
|
|
301
|
-
alignmentDivider.width += missingSpace;
|
|
302
|
-
row.width += missingSpace;
|
|
303
299
|
return;
|
|
304
300
|
}
|
|
301
|
+
super.addInput_(input, activeRow);
|
|
305
302
|
}
|
|
306
|
-
RenderInfo.superClass_.addAlignmentPadding_.call(this, row, missingSpace);
|
|
307
|
-
};
|
|
308
303
|
|
|
309
|
-
/**
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
this.constants_.NOTCH_OFFSET_LEFT + this.constants_.NOTCH_WIDTH;
|
|
318
|
-
let minXPos = notchTotalWidth;
|
|
319
|
-
// Run through every input row on the block and only apply bump logic to the
|
|
320
|
-
// first input row (if the block has prev connection) and every input row that
|
|
321
|
-
// has a prev and next notch.
|
|
322
|
-
for (let i = 2; i < this.rows.length - 1; i += 2) {
|
|
323
|
-
const prevSpacer = this.rows[i - 1];
|
|
324
|
-
const row = this.rows[i];
|
|
325
|
-
const nextSpacer = this.rows[i + 1];
|
|
326
|
-
|
|
327
|
-
const hasPrevNotch = i === 2 ? !!this.topRow.hasPreviousConnection :
|
|
328
|
-
!!prevSpacer.followsStatement;
|
|
329
|
-
const hasNextNotch = i + 2 >= this.rows.length - 1 ?
|
|
330
|
-
!!this.bottomRow.hasNextConnection :
|
|
331
|
-
!!nextSpacer.precedesStatement;
|
|
332
|
-
|
|
333
|
-
if (Types.isInputRow(row) && row.hasStatement) {
|
|
334
|
-
row.measure();
|
|
335
|
-
minXPos = row.width - row.getLastInput().width + notchTotalWidth;
|
|
336
|
-
} else if (
|
|
337
|
-
hasPrevNotch && (i === 2 || hasNextNotch) && Types.isInputRow(row) &&
|
|
338
|
-
!row.hasStatement) {
|
|
339
|
-
let xCursor = row.xPos;
|
|
340
|
-
let prevInRowSpacer = null;
|
|
341
|
-
for (let j = 0; j < row.elements.length; j++) {
|
|
342
|
-
const elem = row.elements[j];
|
|
304
|
+
/**
|
|
305
|
+
* @override
|
|
306
|
+
*/
|
|
307
|
+
addAlignmentPadding_(row, missingSpace) {
|
|
308
|
+
if (this.rightAlignedDummyInputs_.get(row)) {
|
|
309
|
+
let alignmentDivider;
|
|
310
|
+
for (let i = 0; i < row.elements.length; i++) {
|
|
311
|
+
const elem = row.elements[i];
|
|
343
312
|
if (Types.isSpacer(elem)) {
|
|
344
|
-
|
|
313
|
+
alignmentDivider = elem;
|
|
345
314
|
}
|
|
346
|
-
if (
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
(elem.field instanceof FieldLabel ||
|
|
350
|
-
elem.field instanceof FieldImage))) {
|
|
351
|
-
const difference = minXPos - xCursor;
|
|
352
|
-
prevInRowSpacer.width += difference;
|
|
353
|
-
}
|
|
315
|
+
if (Types.isField(elem) && elem instanceof Field &&
|
|
316
|
+
elem.parentInput === this.rightAlignedDummyInputs_.get(row)) {
|
|
317
|
+
break;
|
|
354
318
|
}
|
|
355
|
-
|
|
319
|
+
}
|
|
320
|
+
if (alignmentDivider) {
|
|
321
|
+
alignmentDivider.width += missingSpace;
|
|
322
|
+
row.width += missingSpace;
|
|
323
|
+
return;
|
|
356
324
|
}
|
|
357
325
|
}
|
|
326
|
+
super.addAlignmentPadding_(row, missingSpace);
|
|
358
327
|
}
|
|
359
|
-
};
|
|
360
328
|
|
|
361
|
-
/**
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
329
|
+
/**
|
|
330
|
+
* Adjust the x position of fields to bump all non-label fields in the first
|
|
331
|
+
* row past the notch position. This must be called before ``computeBounds``
|
|
332
|
+
* is called.
|
|
333
|
+
* @protected
|
|
334
|
+
*/
|
|
335
|
+
adjustXPosition_() {
|
|
336
|
+
const notchTotalWidth =
|
|
337
|
+
this.constants_.NOTCH_OFFSET_LEFT + this.constants_.NOTCH_WIDTH;
|
|
338
|
+
let minXPos = notchTotalWidth;
|
|
339
|
+
// Run through every input row on the block and only apply bump logic to the
|
|
340
|
+
// first input row (if the block has prev connection) and every input row
|
|
341
|
+
// that has a prev and next notch.
|
|
342
|
+
for (let i = 2; i < this.rows.length - 1; i += 2) {
|
|
343
|
+
const prevSpacer = /** @type {!SpacerRow} */ (this.rows[i - 1]);
|
|
344
|
+
const row = this.rows[i];
|
|
345
|
+
const nextSpacer = /** @type {!SpacerRow} */ (this.rows[i + 1]);
|
|
346
|
+
|
|
347
|
+
const hasPrevNotch = i === 2 ? !!this.topRow.hasPreviousConnection :
|
|
348
|
+
!!prevSpacer.followsStatement;
|
|
349
|
+
const hasNextNotch = i + 2 >= this.rows.length - 1 ?
|
|
350
|
+
!!this.bottomRow.hasNextConnection :
|
|
351
|
+
!!nextSpacer.precedesStatement;
|
|
352
|
+
|
|
353
|
+
if (Types.isInputRow(row) && row.hasStatement) {
|
|
354
|
+
row.measure();
|
|
355
|
+
minXPos = row.width - row.getLastInput().width + notchTotalWidth;
|
|
356
|
+
} else if (
|
|
357
|
+
hasPrevNotch && (i === 2 || hasNextNotch) && Types.isInputRow(row) &&
|
|
358
|
+
!row.hasStatement) {
|
|
359
|
+
let xCursor = row.xPos;
|
|
360
|
+
let prevInRowSpacer = null;
|
|
361
|
+
for (let j = 0; j < row.elements.length; j++) {
|
|
362
|
+
const elem = row.elements[j];
|
|
363
|
+
if (Types.isSpacer(elem)) {
|
|
364
|
+
prevInRowSpacer = elem;
|
|
365
|
+
}
|
|
366
|
+
if (prevInRowSpacer && (Types.isField(elem) || Types.isInput(elem))) {
|
|
367
|
+
if (xCursor < minXPos &&
|
|
368
|
+
!(Types.isField(elem) && elem instanceof Field &&
|
|
369
|
+
(elem.field instanceof FieldLabel ||
|
|
370
|
+
elem.field instanceof FieldImage))) {
|
|
371
|
+
const difference = minXPos - xCursor;
|
|
372
|
+
prevInRowSpacer.width += difference;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
xCursor += elem.width;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
406
379
|
}
|
|
407
|
-
this.startX = connectionWidth;
|
|
408
|
-
this.width += connectionWidth + rightConnectionWidth;
|
|
409
|
-
this.widthWithChildren += connectionWidth + rightConnectionWidth;
|
|
410
|
-
};
|
|
411
380
|
|
|
412
|
-
/**
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
381
|
+
/**
|
|
382
|
+
* Finalize the output connection info. In particular, set the height of the
|
|
383
|
+
* output connection to match that of the block. For the right side, add a
|
|
384
|
+
* right connection shape element and have it match the dimensions of the
|
|
385
|
+
* output connection.
|
|
386
|
+
* @protected
|
|
387
|
+
*/
|
|
388
|
+
finalizeOutputConnection_() {
|
|
389
|
+
// Dynamic output connections depend on the height of the block.
|
|
390
|
+
if (!this.outputConnection || !this.outputConnection.isDynamicShape) {
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
let yCursor = 0;
|
|
394
|
+
// Determine the block height.
|
|
395
|
+
for (let i = 0; i < this.rows.length; i++) {
|
|
396
|
+
const row = this.rows[i];
|
|
397
|
+
row.yPos = yCursor;
|
|
398
|
+
yCursor += row.height;
|
|
429
399
|
}
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
400
|
+
this.height = yCursor;
|
|
401
|
+
|
|
402
|
+
// Adjust the height of the output connection.
|
|
403
|
+
const blockHeight = this.bottomRow.hasNextConnection ?
|
|
404
|
+
this.height - this.bottomRow.descenderHeight :
|
|
405
|
+
this.height;
|
|
406
|
+
const connectionHeight = this.outputConnection.shape.height(blockHeight);
|
|
407
|
+
const connectionWidth = this.outputConnection.shape.width(blockHeight);
|
|
408
|
+
|
|
409
|
+
this.outputConnection.height = connectionHeight;
|
|
410
|
+
this.outputConnection.width = connectionWidth;
|
|
411
|
+
this.outputConnection.startX = connectionWidth;
|
|
412
|
+
this.outputConnection.connectionOffsetY =
|
|
413
|
+
this.outputConnection.shape.connectionOffsetY(connectionHeight);
|
|
414
|
+
this.outputConnection.connectionOffsetX =
|
|
415
|
+
this.outputConnection.shape.connectionOffsetX(connectionWidth);
|
|
416
|
+
|
|
417
|
+
// Add the right connection measurable.
|
|
418
|
+
// Don't add it if we have a value-to-statement or a value-to-stack block.
|
|
419
|
+
let rightConnectionWidth = 0;
|
|
420
|
+
if (!this.hasStatementInput && !this.bottomRow.hasNextConnection) {
|
|
421
|
+
rightConnectionWidth = connectionWidth;
|
|
422
|
+
this.rightSide.height = connectionHeight;
|
|
423
|
+
this.rightSide.width = rightConnectionWidth;
|
|
424
|
+
this.rightSide.centerline = connectionHeight / 2;
|
|
425
|
+
this.rightSide.xPos = this.width + rightConnectionWidth;
|
|
443
426
|
}
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
427
|
+
this.startX = connectionWidth;
|
|
428
|
+
this.width += connectionWidth + rightConnectionWidth;
|
|
429
|
+
this.widthWithChildren += connectionWidth + rightConnectionWidth;
|
|
447
430
|
}
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* Finalize horizontal alignment of elements on the block. In particular,
|
|
434
|
+
* reduce the implicit spacing created by the left and right output connection
|
|
435
|
+
* shapes by adding setting negative spacing onto the leftmost and rightmost
|
|
436
|
+
* spacers.
|
|
437
|
+
* @protected
|
|
438
|
+
*/
|
|
439
|
+
finalizeHorizontalAlignment_() {
|
|
440
|
+
if (!this.outputConnection || this.hasStatementInput ||
|
|
441
|
+
this.bottomRow.hasNextConnection) {
|
|
442
|
+
return;
|
|
443
|
+
}
|
|
444
|
+
let totalNegativeSpacing = 0;
|
|
452
445
|
for (let i = 0; i < this.rows.length; i++) {
|
|
453
446
|
const row = this.rows[i];
|
|
454
|
-
if (Types.
|
|
455
|
-
|
|
456
|
-
row.elements[1].widthWithConnectedBlocks -= totalNegativeSpacing;
|
|
447
|
+
if (!Types.isInputRow(row)) {
|
|
448
|
+
continue;
|
|
457
449
|
}
|
|
458
|
-
row.
|
|
459
|
-
row.
|
|
450
|
+
const firstElem = row.elements[1];
|
|
451
|
+
const lastElem = row.elements[row.elements.length - 2];
|
|
452
|
+
let leftNegPadding = this.getNegativeSpacing_(firstElem);
|
|
453
|
+
let rightNegPadding = this.getNegativeSpacing_(lastElem);
|
|
454
|
+
totalNegativeSpacing = leftNegPadding + rightNegPadding;
|
|
455
|
+
const minBlockWidth =
|
|
456
|
+
this.constants_.MIN_BLOCK_WIDTH + this.outputConnection.width * 2;
|
|
457
|
+
if (this.width - totalNegativeSpacing < minBlockWidth) {
|
|
458
|
+
// Maintain a minimum block width, split negative spacing between left
|
|
459
|
+
// and right edge.
|
|
460
|
+
totalNegativeSpacing = this.width - minBlockWidth;
|
|
461
|
+
leftNegPadding = totalNegativeSpacing / 2;
|
|
462
|
+
rightNegPadding = totalNegativeSpacing / 2;
|
|
463
|
+
}
|
|
464
|
+
// Add a negative spacer on the start and end of the block.
|
|
465
|
+
row.elements.unshift(new InRowSpacer(this.constants_, -leftNegPadding));
|
|
466
|
+
row.elements.push(new InRowSpacer(this.constants_, -rightNegPadding));
|
|
460
467
|
}
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
RenderInfo.prototype.getNegativeSpacing_ = function(elem) {
|
|
473
|
-
if (!elem) {
|
|
474
|
-
return 0;
|
|
475
|
-
}
|
|
476
|
-
const connectionWidth = this.outputConnection.width;
|
|
477
|
-
const outerShape = this.outputConnection.shape.type;
|
|
478
|
-
const constants =
|
|
479
|
-
/** @type {!ConstantProvider} */ (this.constants_);
|
|
480
|
-
if (this.isMultiRow && this.inputRows.length > 1) {
|
|
481
|
-
switch (outerShape) {
|
|
482
|
-
case constants.SHAPES.ROUND: {
|
|
483
|
-
// Special case for multi-row round reporter blocks.
|
|
484
|
-
const maxWidth = this.constants_.MAX_DYNAMIC_CONNECTION_SHAPE_WIDTH;
|
|
485
|
-
const width = this.height / 2 > maxWidth ? maxWidth : this.height / 2;
|
|
486
|
-
const topPadding = this.constants_.SMALL_PADDING;
|
|
487
|
-
const roundPadding =
|
|
488
|
-
width * (1 - Math.sin(Math.acos((width - topPadding) / width)));
|
|
489
|
-
return connectionWidth - roundPadding;
|
|
468
|
+
if (totalNegativeSpacing) {
|
|
469
|
+
this.width -= totalNegativeSpacing;
|
|
470
|
+
this.widthWithChildren -= totalNegativeSpacing;
|
|
471
|
+
this.rightSide.xPos -= totalNegativeSpacing;
|
|
472
|
+
for (let i = 0; i < this.rows.length; i++) {
|
|
473
|
+
const row = this.rows[i];
|
|
474
|
+
if (Types.isTopOrBottomRow(row)) {
|
|
475
|
+
row.elements[1].width -= totalNegativeSpacing;
|
|
476
|
+
}
|
|
477
|
+
row.width -= totalNegativeSpacing;
|
|
478
|
+
row.widthWithConnectedBlocks -= totalNegativeSpacing;
|
|
490
479
|
}
|
|
491
|
-
default:
|
|
492
|
-
return 0;
|
|
493
480
|
}
|
|
494
481
|
}
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
482
|
+
|
|
483
|
+
/**
|
|
484
|
+
* Calculate the spacing to reduce the left and right edges by based on the
|
|
485
|
+
* outer and inner connection shape.
|
|
486
|
+
* @param {Measurable} elem The first or last element on
|
|
487
|
+
* a block.
|
|
488
|
+
* @return {number} The amount of spacing to reduce the first or last spacer.
|
|
489
|
+
* @protected
|
|
490
|
+
*/
|
|
491
|
+
getNegativeSpacing_(elem) {
|
|
492
|
+
if (!elem) {
|
|
503
493
|
return 0;
|
|
504
494
|
}
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
495
|
+
const connectionWidth = this.outputConnection.width;
|
|
496
|
+
const outerShape = this.outputConnection.shape.type;
|
|
497
|
+
const constants =
|
|
498
|
+
/** @type {!ConstantProvider} */ (this.constants_);
|
|
499
|
+
if (this.isMultiRow && this.inputRows.length > 1) {
|
|
500
|
+
switch (outerShape) {
|
|
501
|
+
case constants.SHAPES.ROUND: {
|
|
502
|
+
// Special case for multi-row round reporter blocks.
|
|
503
|
+
const maxWidth = this.constants_.MAX_DYNAMIC_CONNECTION_SHAPE_WIDTH;
|
|
504
|
+
const width = this.height / 2 > maxWidth ? maxWidth : this.height / 2;
|
|
505
|
+
const topPadding = this.constants_.SMALL_PADDING;
|
|
506
|
+
const roundPadding =
|
|
507
|
+
width * (1 - Math.sin(Math.acos((width - topPadding) / width)));
|
|
508
|
+
return connectionWidth - roundPadding;
|
|
509
|
+
}
|
|
510
|
+
default:
|
|
511
|
+
return 0;
|
|
512
|
+
}
|
|
509
513
|
}
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
514
|
+
if (Types.isInlineInput(elem) && elem instanceof InputConnection) {
|
|
515
|
+
const connectedBlock = elem.connectedBlock;
|
|
516
|
+
const innerShape = connectedBlock ?
|
|
517
|
+
connectedBlock.pathObject.outputShapeType :
|
|
518
|
+
elem.shape.type;
|
|
519
|
+
// Special case for value to stack / value to statement blocks.
|
|
520
|
+
if (connectedBlock && connectedBlock.outputConnection &&
|
|
521
|
+
(connectedBlock.statementInputCount ||
|
|
522
|
+
connectedBlock.nextConnection)) {
|
|
523
|
+
return 0;
|
|
524
|
+
}
|
|
525
|
+
// Special case for hexagonal output.
|
|
526
|
+
if (outerShape === constants.SHAPES.HEXAGONAL &&
|
|
527
|
+
outerShape !== innerShape) {
|
|
528
|
+
return 0;
|
|
529
|
+
}
|
|
530
|
+
return connectionWidth -
|
|
531
|
+
this.constants_.SHAPE_IN_SHAPE_PADDING[outerShape][innerShape];
|
|
532
|
+
} else if (Types.isField(elem) && elem instanceof Field) {
|
|
533
|
+
// Special case for text inputs.
|
|
534
|
+
if (outerShape === constants.SHAPES.ROUND &&
|
|
535
|
+
elem.field instanceof FieldTextInput) {
|
|
536
|
+
return connectionWidth - (2.75 * constants.GRID_UNIT);
|
|
537
|
+
}
|
|
538
|
+
return connectionWidth -
|
|
539
|
+
this.constants_.SHAPE_IN_SHAPE_PADDING[outerShape][0];
|
|
540
|
+
} else if (Types.isIcon(elem)) {
|
|
541
|
+
return this.constants_.SMALL_PADDING;
|
|
517
542
|
}
|
|
518
|
-
return
|
|
519
|
-
this.constants_.SHAPE_IN_SHAPE_PADDING[outerShape][0];
|
|
520
|
-
} else if (Types.isIcon(elem)) {
|
|
521
|
-
return this.constants_.SMALL_PADDING;
|
|
543
|
+
return 0;
|
|
522
544
|
}
|
|
523
|
-
return 0;
|
|
524
|
-
};
|
|
525
545
|
|
|
526
|
-
/**
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
row.height -= this.constants_.MEDIUM_PADDING;
|
|
559
|
-
} else if (!firstRow && !hasNextNotch) {
|
|
560
|
-
// Add a small padding so the notch doesn't clash with inputs/fields.
|
|
561
|
-
prevSpacer.height += this.constants_.SMALL_PADDING;
|
|
562
|
-
} else if (hasNextNotch) {
|
|
563
|
-
// Determine if the input row has non-shadow connected blocks.
|
|
564
|
-
let hasNonShadowConnectedBlocks = false;
|
|
565
|
-
const minVerticalTightNestingHeight = 40;
|
|
566
|
-
for (let j = 0; j < row.elements.length; j++) {
|
|
567
|
-
const elem = row.elements[j];
|
|
568
|
-
if (Types.isInlineInput(elem) && elem.connectedBlock &&
|
|
569
|
-
!elem.connectedBlock.isShadow() &&
|
|
570
|
-
elem.connectedBlock.getHeightWidth().height >=
|
|
571
|
-
minVerticalTightNestingHeight) {
|
|
572
|
-
hasNonShadowConnectedBlocks = true;
|
|
573
|
-
break;
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
// Apply tight-nesting if we have both a prev and next notch and the
|
|
577
|
-
// block has non-shadow connected blocks.
|
|
578
|
-
if (hasNonShadowConnectedBlocks) {
|
|
546
|
+
/**
|
|
547
|
+
* Finalize vertical alignment of rows on a block. In particular, reduce the
|
|
548
|
+
* implicit spacing when a non-shadow block is connected to any of an input
|
|
549
|
+
* row's inline inputs.
|
|
550
|
+
* @protected
|
|
551
|
+
*/
|
|
552
|
+
finalizeVerticalAlignment_() {
|
|
553
|
+
if (this.outputConnection) {
|
|
554
|
+
return;
|
|
555
|
+
}
|
|
556
|
+
// Run through every input row on the block and only apply tight nesting
|
|
557
|
+
// logic to input rows that have a prev and next notch.
|
|
558
|
+
for (let i = 2; i < this.rows.length - 1; i += 2) {
|
|
559
|
+
const prevSpacer = /** @type {!SpacerRow} */ (this.rows[i - 1]);
|
|
560
|
+
const row = this.rows[i];
|
|
561
|
+
const nextSpacer = /** @type {!SpacerRow} */ (this.rows[i + 1]);
|
|
562
|
+
|
|
563
|
+
const firstRow = i === 2;
|
|
564
|
+
const hasPrevNotch = firstRow ? !!this.topRow.hasPreviousConnection :
|
|
565
|
+
!!prevSpacer.followsStatement;
|
|
566
|
+
const hasNextNotch = i + 2 >= this.rows.length - 1 ?
|
|
567
|
+
!!this.bottomRow.hasNextConnection :
|
|
568
|
+
!!nextSpacer.precedesStatement;
|
|
569
|
+
|
|
570
|
+
if (hasPrevNotch) {
|
|
571
|
+
const elem = row.elements[1];
|
|
572
|
+
const hasSingleTextOrImageField = row.elements.length === 3 &&
|
|
573
|
+
elem instanceof Field &&
|
|
574
|
+
(elem.field instanceof FieldLabel ||
|
|
575
|
+
elem.field instanceof FieldImage);
|
|
576
|
+
if (!firstRow && hasSingleTextOrImageField) {
|
|
577
|
+
// Remove some padding if we have a single image or text field.
|
|
579
578
|
prevSpacer.height -= this.constants_.SMALL_PADDING;
|
|
580
579
|
nextSpacer.height -= this.constants_.SMALL_PADDING;
|
|
580
|
+
row.height -= this.constants_.MEDIUM_PADDING;
|
|
581
|
+
} else if (!firstRow && !hasNextNotch) {
|
|
582
|
+
// Add a small padding so the notch doesn't clash with inputs/fields.
|
|
583
|
+
prevSpacer.height += this.constants_.SMALL_PADDING;
|
|
584
|
+
} else if (hasNextNotch) {
|
|
585
|
+
// Determine if the input row has non-shadow connected blocks.
|
|
586
|
+
let hasNonShadowConnectedBlocks = false;
|
|
587
|
+
const minVerticalTightNestingHeight = 40;
|
|
588
|
+
for (let j = 0; j < row.elements.length; j++) {
|
|
589
|
+
const elem = row.elements[j];
|
|
590
|
+
if (elem instanceof InputConnection && Types.isInlineInput(elem) &&
|
|
591
|
+
elem.connectedBlock && !elem.connectedBlock.isShadow() &&
|
|
592
|
+
elem.connectedBlock.getHeightWidth().height >=
|
|
593
|
+
minVerticalTightNestingHeight) {
|
|
594
|
+
hasNonShadowConnectedBlocks = true;
|
|
595
|
+
break;
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
// Apply tight-nesting if we have both a prev and next notch and the
|
|
599
|
+
// block has non-shadow connected blocks.
|
|
600
|
+
if (hasNonShadowConnectedBlocks) {
|
|
601
|
+
prevSpacer.height -= this.constants_.SMALL_PADDING;
|
|
602
|
+
nextSpacer.height -= this.constants_.SMALL_PADDING;
|
|
603
|
+
}
|
|
581
604
|
}
|
|
582
605
|
}
|
|
583
606
|
}
|
|
584
607
|
}
|
|
585
|
-
};
|
|
586
608
|
|
|
587
|
-
/**
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
609
|
+
/**
|
|
610
|
+
* @override
|
|
611
|
+
*/
|
|
612
|
+
finalize_() {
|
|
613
|
+
this.finalizeOutputConnection_();
|
|
614
|
+
this.finalizeHorizontalAlignment_();
|
|
615
|
+
this.finalizeVerticalAlignment_();
|
|
616
|
+
super.finalize_();
|
|
617
|
+
|
|
618
|
+
if (this.rightSide) {
|
|
619
|
+
this.widthWithChildren += this.rightSide.width;
|
|
620
|
+
}
|
|
598
621
|
}
|
|
599
|
-
}
|
|
622
|
+
}
|
|
600
623
|
|
|
601
624
|
exports.RenderInfo = RenderInfo;
|