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