blockly 7.20211209.4 → 8.0.1
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 +5 -4
- package/blockly_compressed.js +4 -3
- 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 +45 -32
- package/blocks/text.js +22 -13
- package/blocks/variables.js +14 -3
- package/blocks/variables_dynamic.js +13 -3
- package/blocks_compressed.js +1 -1
- 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 +26 -10
- 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/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/msg/smn.js +436 -0
- package/package.json +7 -6
- package/blocks/all.js +0 -23
|
@@ -17,12 +17,11 @@ goog.module('Blockly.HorizontalFlyout');
|
|
|
17
17
|
|
|
18
18
|
const WidgetDiv = goog.require('Blockly.WidgetDiv');
|
|
19
19
|
const browserEvents = goog.require('Blockly.browserEvents');
|
|
20
|
-
const
|
|
20
|
+
const dropDownDiv = goog.require('Blockly.dropDownDiv');
|
|
21
21
|
const registry = goog.require('Blockly.registry');
|
|
22
22
|
const toolbox = goog.require('Blockly.utils.toolbox');
|
|
23
23
|
/* eslint-disable-next-line no-unused-vars */
|
|
24
24
|
const {Coordinate} = goog.requireType('Blockly.utils.Coordinate');
|
|
25
|
-
const {DropDownDiv} = goog.require('Blockly.DropDownDiv');
|
|
26
25
|
const {Flyout} = goog.require('Blockly.Flyout');
|
|
27
26
|
/* eslint-disable-next-line no-unused-vars */
|
|
28
27
|
const {Options} = goog.requireType('Blockly.Options');
|
|
@@ -32,355 +31,358 @@ const {Scrollbar} = goog.require('Blockly.Scrollbar');
|
|
|
32
31
|
|
|
33
32
|
/**
|
|
34
33
|
* Class for a flyout.
|
|
35
|
-
* @param {!Options} workspaceOptions Dictionary of options for the
|
|
36
|
-
* workspace.
|
|
37
34
|
* @extends {Flyout}
|
|
38
|
-
* @constructor
|
|
39
35
|
* @alias Blockly.HorizontalFlyout
|
|
40
36
|
*/
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
* @param {!{x:number,y:number}} xyRatio Contains a y property which is a float
|
|
50
|
-
* between 0 and 1 specifying the degree of scrolling and a
|
|
51
|
-
* similar x property.
|
|
52
|
-
* @protected
|
|
53
|
-
*/
|
|
54
|
-
HorizontalFlyout.prototype.setMetrics_ = function(xyRatio) {
|
|
55
|
-
if (!this.isVisible()) {
|
|
56
|
-
return;
|
|
37
|
+
class HorizontalFlyout extends Flyout {
|
|
38
|
+
/**
|
|
39
|
+
* @param {!Options} workspaceOptions Dictionary of options for the
|
|
40
|
+
* workspace.
|
|
41
|
+
*/
|
|
42
|
+
constructor(workspaceOptions) {
|
|
43
|
+
super(workspaceOptions);
|
|
44
|
+
this.horizontalLayout = true;
|
|
57
45
|
}
|
|
58
46
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
47
|
+
/**
|
|
48
|
+
* Sets the translation of the flyout to match the scrollbars.
|
|
49
|
+
* @param {!{x:number,y:number}} xyRatio Contains a y property which is a
|
|
50
|
+
* float between 0 and 1 specifying the degree of scrolling and a similar
|
|
51
|
+
* x property.
|
|
52
|
+
* @protected
|
|
53
|
+
*/
|
|
54
|
+
setMetrics_(xyRatio) {
|
|
55
|
+
if (!this.isVisible()) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
63
58
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
}
|
|
59
|
+
const metricsManager = this.workspace_.getMetricsManager();
|
|
60
|
+
const scrollMetrics = metricsManager.getScrollMetrics();
|
|
61
|
+
const viewMetrics = metricsManager.getViewMetrics();
|
|
62
|
+
const absoluteMetrics = metricsManager.getAbsoluteMetrics();
|
|
69
63
|
|
|
70
|
-
|
|
71
|
-
this.workspace_.scrollX
|
|
72
|
-
|
|
73
|
-
|
|
64
|
+
if (typeof xyRatio.x === 'number') {
|
|
65
|
+
this.workspace_.scrollX =
|
|
66
|
+
-(scrollMetrics.left +
|
|
67
|
+
(scrollMetrics.width - viewMetrics.width) * xyRatio.x);
|
|
68
|
+
}
|
|
74
69
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
HorizontalFlyout.prototype.getX = function() {
|
|
80
|
-
// X is always 0 since this is a horizontal flyout.
|
|
81
|
-
return 0;
|
|
82
|
-
};
|
|
70
|
+
this.workspace_.translate(
|
|
71
|
+
this.workspace_.scrollX + absoluteMetrics.left,
|
|
72
|
+
this.workspace_.scrollY + absoluteMetrics.top);
|
|
73
|
+
}
|
|
83
74
|
|
|
84
|
-
/**
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
75
|
+
/**
|
|
76
|
+
* Calculates the x coordinate for the flyout position.
|
|
77
|
+
* @return {number} X coordinate.
|
|
78
|
+
*/
|
|
79
|
+
getX() {
|
|
80
|
+
// X is always 0 since this is a horizontal flyout.
|
|
90
81
|
return 0;
|
|
91
82
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Calculates the y coordinate for the flyout position.
|
|
86
|
+
* @return {number} Y coordinate.
|
|
87
|
+
*/
|
|
88
|
+
getY() {
|
|
89
|
+
if (!this.isVisible()) {
|
|
90
|
+
return 0;
|
|
91
|
+
}
|
|
92
|
+
const metricsManager = this.targetWorkspace.getMetricsManager();
|
|
93
|
+
const absoluteMetrics = metricsManager.getAbsoluteMetrics();
|
|
94
|
+
const viewMetrics = metricsManager.getViewMetrics();
|
|
95
|
+
const toolboxMetrics = metricsManager.getToolboxMetrics();
|
|
96
|
+
|
|
97
|
+
let y = 0;
|
|
98
|
+
const atTop = this.toolboxPosition_ === toolbox.Position.TOP;
|
|
99
|
+
// If this flyout is not the trashcan flyout (e.g. toolbox or mutator).
|
|
100
|
+
if (this.targetWorkspace.toolboxPosition === this.toolboxPosition_) {
|
|
101
|
+
// If there is a category toolbox.
|
|
102
|
+
if (this.targetWorkspace.getToolbox()) {
|
|
103
|
+
if (atTop) {
|
|
104
|
+
y = toolboxMetrics.height;
|
|
105
|
+
} else {
|
|
106
|
+
y = viewMetrics.height - this.height_;
|
|
107
|
+
}
|
|
108
|
+
// Simple (flyout-only) toolbox.
|
|
105
109
|
} else {
|
|
106
|
-
|
|
110
|
+
if (atTop) {
|
|
111
|
+
y = 0;
|
|
112
|
+
} else {
|
|
113
|
+
// The simple flyout does not cover the workspace.
|
|
114
|
+
y = viewMetrics.height;
|
|
115
|
+
}
|
|
107
116
|
}
|
|
108
|
-
//
|
|
117
|
+
// Trashcan flyout is opposite the main flyout.
|
|
109
118
|
} else {
|
|
110
119
|
if (atTop) {
|
|
111
120
|
y = 0;
|
|
112
121
|
} else {
|
|
113
|
-
//
|
|
114
|
-
|
|
122
|
+
// Because the anchor point of the flyout is on the top, but we want
|
|
123
|
+
// to align the bottom edge of the flyout with the bottom edge of the
|
|
124
|
+
// blocklyDiv, we calculate the full height of the div minus the height
|
|
125
|
+
// of the flyout.
|
|
126
|
+
y = viewMetrics.height + absoluteMetrics.top - this.height_;
|
|
115
127
|
}
|
|
116
128
|
}
|
|
117
|
-
// Trashcan flyout is opposite the main flyout.
|
|
118
|
-
} else {
|
|
119
|
-
if (atTop) {
|
|
120
|
-
y = 0;
|
|
121
|
-
} else {
|
|
122
|
-
// Because the anchor point of the flyout is on the top, but we want
|
|
123
|
-
// to align the bottom edge of the flyout with the bottom edge of the
|
|
124
|
-
// blocklyDiv, we calculate the full height of the div minus the height
|
|
125
|
-
// of the flyout.
|
|
126
|
-
y = viewMetrics.height + absoluteMetrics.top - this.height_;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
129
|
|
|
130
|
-
|
|
131
|
-
};
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* Move the flyout to the edge of the workspace.
|
|
135
|
-
*/
|
|
136
|
-
HorizontalFlyout.prototype.position = function() {
|
|
137
|
-
if (!this.isVisible() || !this.targetWorkspace.isVisible()) {
|
|
138
|
-
return;
|
|
130
|
+
return y;
|
|
139
131
|
}
|
|
140
|
-
const metricsManager = this.targetWorkspace.getMetricsManager();
|
|
141
|
-
const targetWorkspaceViewMetrics = metricsManager.getViewMetrics();
|
|
142
132
|
|
|
143
|
-
|
|
144
|
-
|
|
133
|
+
/**
|
|
134
|
+
* Move the flyout to the edge of the workspace.
|
|
135
|
+
*/
|
|
136
|
+
position() {
|
|
137
|
+
if (!this.isVisible() || !this.targetWorkspace.isVisible()) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
const metricsManager = this.targetWorkspace.getMetricsManager();
|
|
141
|
+
const targetWorkspaceViewMetrics = metricsManager.getViewMetrics();
|
|
145
142
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
this.setBackgroundPath_(edgeWidth, edgeHeight);
|
|
143
|
+
// Record the width for workspace metrics.
|
|
144
|
+
this.width_ = targetWorkspaceViewMetrics.width;
|
|
149
145
|
|
|
150
|
-
|
|
151
|
-
|
|
146
|
+
const edgeWidth = targetWorkspaceViewMetrics.width - 2 * this.CORNER_RADIUS;
|
|
147
|
+
const edgeHeight = this.height_ - this.CORNER_RADIUS;
|
|
148
|
+
this.setBackgroundPath_(edgeWidth, edgeHeight);
|
|
152
149
|
|
|
153
|
-
|
|
154
|
-
|
|
150
|
+
const x = this.getX();
|
|
151
|
+
const y = this.getY();
|
|
155
152
|
|
|
156
|
-
|
|
157
|
-
* Create and set the path for the visible boundaries of the flyout.
|
|
158
|
-
* @param {number} width The width of the flyout, not including the
|
|
159
|
-
* rounded corners.
|
|
160
|
-
* @param {number} height The height of the flyout, not including
|
|
161
|
-
* rounded corners.
|
|
162
|
-
* @private
|
|
163
|
-
*/
|
|
164
|
-
HorizontalFlyout.prototype.setBackgroundPath_ = function(width, height) {
|
|
165
|
-
const atTop = this.toolboxPosition_ === toolbox.Position.TOP;
|
|
166
|
-
// Start at top left.
|
|
167
|
-
const path = ['M 0,' + (atTop ? 0 : this.CORNER_RADIUS)];
|
|
168
|
-
|
|
169
|
-
if (atTop) {
|
|
170
|
-
// Top.
|
|
171
|
-
path.push('h', width + 2 * this.CORNER_RADIUS);
|
|
172
|
-
// Right.
|
|
173
|
-
path.push('v', height);
|
|
174
|
-
// Bottom.
|
|
175
|
-
path.push(
|
|
176
|
-
'a', this.CORNER_RADIUS, this.CORNER_RADIUS, 0, 0, 1,
|
|
177
|
-
-this.CORNER_RADIUS, this.CORNER_RADIUS);
|
|
178
|
-
path.push('h', -width);
|
|
179
|
-
// Left.
|
|
180
|
-
path.push(
|
|
181
|
-
'a', this.CORNER_RADIUS, this.CORNER_RADIUS, 0, 0, 1,
|
|
182
|
-
-this.CORNER_RADIUS, -this.CORNER_RADIUS);
|
|
183
|
-
path.push('z');
|
|
184
|
-
} else {
|
|
185
|
-
// Top.
|
|
186
|
-
path.push(
|
|
187
|
-
'a', this.CORNER_RADIUS, this.CORNER_RADIUS, 0, 0, 1,
|
|
188
|
-
this.CORNER_RADIUS, -this.CORNER_RADIUS);
|
|
189
|
-
path.push('h', width);
|
|
190
|
-
// Right.
|
|
191
|
-
path.push(
|
|
192
|
-
'a', this.CORNER_RADIUS, this.CORNER_RADIUS, 0, 0, 1,
|
|
193
|
-
this.CORNER_RADIUS, this.CORNER_RADIUS);
|
|
194
|
-
path.push('v', height);
|
|
195
|
-
// Bottom.
|
|
196
|
-
path.push('h', -width - 2 * this.CORNER_RADIUS);
|
|
197
|
-
// Left.
|
|
198
|
-
path.push('z');
|
|
153
|
+
this.positionAt_(this.width_, this.height_, x, y);
|
|
199
154
|
}
|
|
200
|
-
this.svgBackground_.setAttribute('d', path.join(' '));
|
|
201
|
-
};
|
|
202
|
-
|
|
203
|
-
/**
|
|
204
|
-
* Scroll the flyout to the top.
|
|
205
|
-
*/
|
|
206
|
-
HorizontalFlyout.prototype.scrollToStart = function() {
|
|
207
|
-
this.workspace_.scrollbar.setX(this.RTL ? Infinity : 0);
|
|
208
|
-
};
|
|
209
|
-
|
|
210
|
-
/**
|
|
211
|
-
* Scroll the flyout.
|
|
212
|
-
* @param {!Event} e Mouse wheel scroll event.
|
|
213
|
-
* @protected
|
|
214
|
-
*/
|
|
215
|
-
HorizontalFlyout.prototype.wheel_ = function(e) {
|
|
216
|
-
const scrollDelta = browserEvents.getScrollDeltaPixels(e);
|
|
217
|
-
const delta = scrollDelta.x || scrollDelta.y;
|
|
218
155
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
156
|
+
/**
|
|
157
|
+
* Create and set the path for the visible boundaries of the flyout.
|
|
158
|
+
* @param {number} width The width of the flyout, not including the
|
|
159
|
+
* rounded corners.
|
|
160
|
+
* @param {number} height The height of the flyout, not including
|
|
161
|
+
* rounded corners.
|
|
162
|
+
* @private
|
|
163
|
+
*/
|
|
164
|
+
setBackgroundPath_(width, height) {
|
|
165
|
+
const atTop = this.toolboxPosition_ === toolbox.Position.TOP;
|
|
166
|
+
// Start at top left.
|
|
167
|
+
const path = ['M 0,' + (atTop ? 0 : this.CORNER_RADIUS)];
|
|
223
168
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
169
|
+
if (atTop) {
|
|
170
|
+
// Top.
|
|
171
|
+
path.push('h', width + 2 * this.CORNER_RADIUS);
|
|
172
|
+
// Right.
|
|
173
|
+
path.push('v', height);
|
|
174
|
+
// Bottom.
|
|
175
|
+
path.push(
|
|
176
|
+
'a', this.CORNER_RADIUS, this.CORNER_RADIUS, 0, 0, 1,
|
|
177
|
+
-this.CORNER_RADIUS, this.CORNER_RADIUS);
|
|
178
|
+
path.push('h', -width);
|
|
179
|
+
// Left.
|
|
180
|
+
path.push(
|
|
181
|
+
'a', this.CORNER_RADIUS, this.CORNER_RADIUS, 0, 0, 1,
|
|
182
|
+
-this.CORNER_RADIUS, -this.CORNER_RADIUS);
|
|
183
|
+
path.push('z');
|
|
184
|
+
} else {
|
|
185
|
+
// Top.
|
|
186
|
+
path.push(
|
|
187
|
+
'a', this.CORNER_RADIUS, this.CORNER_RADIUS, 0, 0, 1,
|
|
188
|
+
this.CORNER_RADIUS, -this.CORNER_RADIUS);
|
|
189
|
+
path.push('h', width);
|
|
190
|
+
// Right.
|
|
191
|
+
path.push(
|
|
192
|
+
'a', this.CORNER_RADIUS, this.CORNER_RADIUS, 0, 0, 1,
|
|
193
|
+
this.CORNER_RADIUS, this.CORNER_RADIUS);
|
|
194
|
+
path.push('v', height);
|
|
195
|
+
// Bottom.
|
|
196
|
+
path.push('h', -width - 2 * this.CORNER_RADIUS);
|
|
197
|
+
// Left.
|
|
198
|
+
path.push('z');
|
|
199
|
+
}
|
|
200
|
+
this.svgBackground_.setAttribute('d', path.join(' '));
|
|
229
201
|
}
|
|
230
202
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
/**
|
|
238
|
-
* Lay out the blocks in the flyout.
|
|
239
|
-
* @param {!Array<!Object>} contents The blocks and buttons to lay out.
|
|
240
|
-
* @param {!Array<number>} gaps The visible gaps between blocks.
|
|
241
|
-
* @protected
|
|
242
|
-
*/
|
|
243
|
-
HorizontalFlyout.prototype.layout_ = function(contents, gaps) {
|
|
244
|
-
this.workspace_.scale = this.targetWorkspace.scale;
|
|
245
|
-
const margin = this.MARGIN;
|
|
246
|
-
let cursorX = margin + this.tabWidth_;
|
|
247
|
-
const cursorY = margin;
|
|
248
|
-
if (this.RTL) {
|
|
249
|
-
contents = contents.reverse();
|
|
203
|
+
/**
|
|
204
|
+
* Scroll the flyout to the top.
|
|
205
|
+
*/
|
|
206
|
+
scrollToStart() {
|
|
207
|
+
this.workspace_.scrollbar.setX(this.RTL ? Infinity : 0);
|
|
250
208
|
}
|
|
251
209
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
const
|
|
264
|
-
const
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
}
|
|
274
|
-
block.moveBy(moveX, cursorY);
|
|
210
|
+
/**
|
|
211
|
+
* Scroll the flyout.
|
|
212
|
+
* @param {!Event} e Mouse wheel scroll event.
|
|
213
|
+
* @protected
|
|
214
|
+
*/
|
|
215
|
+
wheel_(e) {
|
|
216
|
+
const scrollDelta = browserEvents.getScrollDeltaPixels(e);
|
|
217
|
+
const delta = scrollDelta.x || scrollDelta.y;
|
|
218
|
+
|
|
219
|
+
if (delta) {
|
|
220
|
+
const metricsManager = this.workspace_.getMetricsManager();
|
|
221
|
+
const scrollMetrics = metricsManager.getScrollMetrics();
|
|
222
|
+
const viewMetrics = metricsManager.getViewMetrics();
|
|
223
|
+
|
|
224
|
+
const pos = (viewMetrics.left - scrollMetrics.left) + delta;
|
|
225
|
+
this.workspace_.scrollbar.setX(pos);
|
|
226
|
+
// When the flyout moves from a wheel event, hide WidgetDiv and
|
|
227
|
+
// dropDownDiv.
|
|
228
|
+
WidgetDiv.hide();
|
|
229
|
+
dropDownDiv.hideWithoutAnimation();
|
|
230
|
+
}
|
|
275
231
|
|
|
276
|
-
|
|
277
|
-
|
|
232
|
+
// Don't scroll the page.
|
|
233
|
+
e.preventDefault();
|
|
234
|
+
// Don't propagate mousewheel event (zooming).
|
|
235
|
+
e.stopPropagation();
|
|
236
|
+
}
|
|
278
237
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
238
|
+
/**
|
|
239
|
+
* Lay out the blocks in the flyout.
|
|
240
|
+
* @param {!Array<!Object>} contents The blocks and buttons to lay out.
|
|
241
|
+
* @param {!Array<number>} gaps The visible gaps between blocks.
|
|
242
|
+
* @protected
|
|
243
|
+
*/
|
|
244
|
+
layout_(contents, gaps) {
|
|
245
|
+
this.workspace_.scale = this.targetWorkspace.scale;
|
|
246
|
+
const margin = this.MARGIN;
|
|
247
|
+
let cursorX = margin + this.tabWidth_;
|
|
248
|
+
const cursorY = margin;
|
|
249
|
+
if (this.RTL) {
|
|
250
|
+
contents = contents.reverse();
|
|
283
251
|
}
|
|
284
|
-
}
|
|
285
|
-
};
|
|
286
252
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
253
|
+
for (let i = 0, item; (item = contents[i]); i++) {
|
|
254
|
+
if (item.type === 'block') {
|
|
255
|
+
const block = item.block;
|
|
256
|
+
const allBlocks = block.getDescendants(false);
|
|
257
|
+
for (let j = 0, child; (child = allBlocks[j]); j++) {
|
|
258
|
+
// Mark blocks as being inside a flyout. This is used to detect and
|
|
259
|
+
// prevent the closure of the flyout if the user right-clicks on such
|
|
260
|
+
// a block.
|
|
261
|
+
child.isInFlyout = true;
|
|
262
|
+
}
|
|
263
|
+
block.render();
|
|
264
|
+
const root = block.getSvgRoot();
|
|
265
|
+
const blockHW = block.getHeightWidth();
|
|
266
|
+
|
|
267
|
+
// Figure out where to place the block.
|
|
268
|
+
const tab = block.outputConnection ? this.tabWidth_ : 0;
|
|
269
|
+
let moveX;
|
|
270
|
+
if (this.RTL) {
|
|
271
|
+
moveX = cursorX + blockHW.width;
|
|
272
|
+
} else {
|
|
273
|
+
moveX = cursorX - tab;
|
|
274
|
+
}
|
|
275
|
+
block.moveBy(moveX, cursorY);
|
|
276
|
+
|
|
277
|
+
const rect = this.createRect_(block, moveX, cursorY, blockHW, i);
|
|
278
|
+
cursorX += (blockHW.width + gaps[i]);
|
|
279
|
+
|
|
280
|
+
this.addBlockListeners_(root, block, rect);
|
|
281
|
+
} else if (item.type === 'button') {
|
|
282
|
+
this.initFlyoutButton_(item.button, cursorX, cursorY);
|
|
283
|
+
cursorX += (item.button.width + gaps[i]);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
308
286
|
}
|
|
309
|
-
return false;
|
|
310
|
-
};
|
|
311
287
|
|
|
312
|
-
/**
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
288
|
+
/**
|
|
289
|
+
* Determine if a drag delta is toward the workspace, based on the position
|
|
290
|
+
* and orientation of the flyout. This is used in determineDragIntention_ to
|
|
291
|
+
* determine if a new block should be created or if the flyout should scroll.
|
|
292
|
+
* @param {!Coordinate} currentDragDeltaXY How far the pointer has
|
|
293
|
+
* moved from the position at mouse down, in pixel units.
|
|
294
|
+
* @return {boolean} True if the drag is toward the workspace.
|
|
295
|
+
* @package
|
|
296
|
+
*/
|
|
297
|
+
isDragTowardWorkspace(currentDragDeltaXY) {
|
|
298
|
+
const dx = currentDragDeltaXY.x;
|
|
299
|
+
const dy = currentDragDeltaXY.y;
|
|
300
|
+
// Direction goes from -180 to 180, with 0 toward the right and 90 on top.
|
|
301
|
+
const dragDirection = Math.atan2(dy, dx) / Math.PI * 180;
|
|
302
|
+
|
|
303
|
+
const range = this.dragAngleRange_;
|
|
304
|
+
// Check for up or down dragging.
|
|
305
|
+
if ((dragDirection < 90 + range && dragDirection > 90 - range) ||
|
|
306
|
+
(dragDirection > -90 - range && dragDirection < -90 + range)) {
|
|
307
|
+
return true;
|
|
308
|
+
}
|
|
309
|
+
return false;
|
|
323
310
|
}
|
|
324
311
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
}
|
|
338
|
-
};
|
|
312
|
+
/**
|
|
313
|
+
* Returns the bounding rectangle of the drag target area in pixel units
|
|
314
|
+
* relative to viewport.
|
|
315
|
+
* @return {?Rect} The component's bounding box. Null if drag
|
|
316
|
+
* target area should be ignored.
|
|
317
|
+
*/
|
|
318
|
+
getClientRect() {
|
|
319
|
+
if (!this.svgGroup_ || this.autoClose || !this.isVisible()) {
|
|
320
|
+
// The bounding rectangle won't compute correctly if the flyout is closed
|
|
321
|
+
// and auto-close flyouts aren't valid drag targets (or delete areas).
|
|
322
|
+
return null;
|
|
323
|
+
}
|
|
339
324
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
flyoutHeight = Math.max(flyoutHeight, button.height);
|
|
325
|
+
const flyoutRect = this.svgGroup_.getBoundingClientRect();
|
|
326
|
+
// BIG_NUM is offscreen padding so that blocks dragged beyond the shown
|
|
327
|
+
// flyout area are still deleted. Must be larger than the largest screen
|
|
328
|
+
// size, but be smaller than half Number.MAX_SAFE_INTEGER (not available on
|
|
329
|
+
// IE).
|
|
330
|
+
const BIG_NUM = 1000000000;
|
|
331
|
+
const top = flyoutRect.top;
|
|
332
|
+
|
|
333
|
+
if (this.toolboxPosition_ === toolbox.Position.TOP) {
|
|
334
|
+
const height = flyoutRect.height;
|
|
335
|
+
return new Rect(-BIG_NUM, top + height, -BIG_NUM, BIG_NUM);
|
|
336
|
+
} else { // Bottom.
|
|
337
|
+
return new Rect(top, BIG_NUM, -BIG_NUM, BIG_NUM);
|
|
338
|
+
}
|
|
355
339
|
}
|
|
356
|
-
flyoutHeight += this.MARGIN * 1.5;
|
|
357
|
-
flyoutHeight *= this.workspace_.scale;
|
|
358
|
-
flyoutHeight += Scrollbar.scrollbarThickness;
|
|
359
340
|
|
|
360
|
-
|
|
341
|
+
/**
|
|
342
|
+
* Compute height of flyout. toolbox.Position mat under each block.
|
|
343
|
+
* For RTL: Lay out the blocks right-aligned.
|
|
344
|
+
* @protected
|
|
345
|
+
*/
|
|
346
|
+
reflowInternal_() {
|
|
347
|
+
this.workspace_.scale = this.getFlyoutScale();
|
|
348
|
+
let flyoutHeight = 0;
|
|
349
|
+
const blocks = this.workspace_.getTopBlocks(false);
|
|
361
350
|
for (let i = 0, block; (block = blocks[i]); i++) {
|
|
362
|
-
|
|
363
|
-
this.moveRectToBlock_(block.flyoutRect_, block);
|
|
364
|
-
}
|
|
351
|
+
flyoutHeight = Math.max(flyoutHeight, block.getHeightWidth().height);
|
|
365
352
|
}
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
!this.targetWorkspace.getToolbox()) {
|
|
370
|
-
// This flyout is a simple toolbox. Reposition the workspace so that (0,0)
|
|
371
|
-
// is in the correct position relative to the new absolute edge (ie
|
|
372
|
-
// toolbox edge).
|
|
373
|
-
this.targetWorkspace.translate(
|
|
374
|
-
this.targetWorkspace.scrollX,
|
|
375
|
-
this.targetWorkspace.scrollY + flyoutHeight);
|
|
353
|
+
const buttons = this.buttons_;
|
|
354
|
+
for (let i = 0, button; (button = buttons[i]); i++) {
|
|
355
|
+
flyoutHeight = Math.max(flyoutHeight, button.height);
|
|
376
356
|
}
|
|
357
|
+
flyoutHeight += this.MARGIN * 1.5;
|
|
358
|
+
flyoutHeight *= this.workspace_.scale;
|
|
359
|
+
flyoutHeight += Scrollbar.scrollbarThickness;
|
|
360
|
+
|
|
361
|
+
if (this.height_ !== flyoutHeight) {
|
|
362
|
+
for (let i = 0, block; (block = blocks[i]); i++) {
|
|
363
|
+
if (this.rectMap_.has(block)) {
|
|
364
|
+
this.moveRectToBlock_(this.rectMap_.get(block), block);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
if (this.targetWorkspace.toolboxPosition === this.toolboxPosition_ &&
|
|
369
|
+
this.toolboxPosition_ === toolbox.Position.TOP &&
|
|
370
|
+
!this.targetWorkspace.getToolbox()) {
|
|
371
|
+
// This flyout is a simple toolbox. Reposition the workspace so that
|
|
372
|
+
// (0,0) is in the correct position relative to the new absolute edge
|
|
373
|
+
// (ie toolbox edge).
|
|
374
|
+
this.targetWorkspace.translate(
|
|
375
|
+
this.targetWorkspace.scrollX,
|
|
376
|
+
this.targetWorkspace.scrollY + flyoutHeight);
|
|
377
|
+
}
|
|
377
378
|
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
379
|
+
// Record the height for workspace metrics and .position.
|
|
380
|
+
this.height_ = flyoutHeight;
|
|
381
|
+
this.position();
|
|
382
|
+
this.targetWorkspace.recordDragTargets();
|
|
383
|
+
}
|
|
382
384
|
}
|
|
383
|
-
}
|
|
385
|
+
}
|
|
384
386
|
|
|
385
387
|
registry.register(
|
|
386
388
|
registry.Type.FLYOUTS_HORIZONTAL_TOOLBOX, registry.DEFAULT,
|