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
package/core/gesture.js
CHANGED
|
@@ -28,6 +28,7 @@ const registry = goog.require('Blockly.registry');
|
|
|
28
28
|
/* eslint-disable-next-line no-unused-vars */
|
|
29
29
|
const {BlockSvg} = goog.requireType('Blockly.BlockSvg');
|
|
30
30
|
const {BubbleDragger} = goog.require('Blockly.BubbleDragger');
|
|
31
|
+
const {config} = goog.require('Blockly.config');
|
|
31
32
|
const {Coordinate} = goog.require('Blockly.utils.Coordinate');
|
|
32
33
|
/* eslint-disable-next-line no-unused-vars */
|
|
33
34
|
const {Field} = goog.requireType('Blockly.Field');
|
|
@@ -55,956 +56,971 @@ goog.require('Blockly.Events.Click');
|
|
|
55
56
|
|
|
56
57
|
/**
|
|
57
58
|
* Class for one gesture.
|
|
58
|
-
* @param {!Event} e The event that kicked off this gesture.
|
|
59
|
-
* @param {!WorkspaceSvg} creatorWorkspace The workspace that created
|
|
60
|
-
* this gesture and has a reference to it.
|
|
61
|
-
* @constructor
|
|
62
59
|
* @alias Blockly.Gesture
|
|
63
60
|
*/
|
|
64
|
-
|
|
61
|
+
class Gesture {
|
|
65
62
|
/**
|
|
66
|
-
* The
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
* @private
|
|
63
|
+
* @param {!Event} e The event that kicked off this gesture.
|
|
64
|
+
* @param {!WorkspaceSvg} creatorWorkspace The workspace that created
|
|
65
|
+
* this gesture and has a reference to it.
|
|
70
66
|
*/
|
|
71
|
-
|
|
67
|
+
constructor(e, creatorWorkspace) {
|
|
68
|
+
/**
|
|
69
|
+
* The position of the mouse when the gesture started. Units are CSS
|
|
70
|
+
* pixels, with (0, 0) at the top left of the browser window (mouseEvent
|
|
71
|
+
* clientX/Y).
|
|
72
|
+
* @type {Coordinate}
|
|
73
|
+
* @private
|
|
74
|
+
*/
|
|
75
|
+
this.mouseDownXY_ = null;
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* How far the mouse has moved during this drag, in pixel units.
|
|
79
|
+
* (0, 0) is at this.mouseDownXY_.
|
|
80
|
+
* @type {!Coordinate}
|
|
81
|
+
* @private
|
|
82
|
+
*/
|
|
83
|
+
this.currentDragDeltaXY_ = new Coordinate(0, 0);
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* The bubble that the gesture started on, or null if it did not start on a
|
|
87
|
+
* bubble.
|
|
88
|
+
* @type {IBubble}
|
|
89
|
+
* @private
|
|
90
|
+
*/
|
|
91
|
+
this.startBubble_ = null;
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* The field that the gesture started on, or null if it did not start on a
|
|
95
|
+
* field.
|
|
96
|
+
* @type {Field}
|
|
97
|
+
* @private
|
|
98
|
+
*/
|
|
99
|
+
this.startField_ = null;
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* The block that the gesture started on, or null if it did not start on a
|
|
103
|
+
* block.
|
|
104
|
+
* @type {BlockSvg}
|
|
105
|
+
* @private
|
|
106
|
+
*/
|
|
107
|
+
this.startBlock_ = null;
|
|
72
108
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
109
|
+
/**
|
|
110
|
+
* The block that this gesture targets. If the gesture started on a
|
|
111
|
+
* shadow block, this is the first non-shadow parent of the block. If the
|
|
112
|
+
* gesture started in the flyout, this is the root block of the block group
|
|
113
|
+
* that was clicked or dragged.
|
|
114
|
+
* @type {BlockSvg}
|
|
115
|
+
* @private
|
|
116
|
+
*/
|
|
117
|
+
this.targetBlock_ = null;
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* The workspace that the gesture started on. There may be multiple
|
|
121
|
+
* workspaces on a page; this is more accurate than using
|
|
122
|
+
* Blockly.common.getMainWorkspace().
|
|
123
|
+
* @type {WorkspaceSvg}
|
|
124
|
+
* @protected
|
|
125
|
+
*/
|
|
126
|
+
this.startWorkspace_ = null;
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* The workspace that created this gesture. This workspace keeps a
|
|
130
|
+
* reference to the gesture, which will need to be cleared at deletion. This
|
|
131
|
+
* may be different from the start workspace. For instance, a flyout is a
|
|
132
|
+
* workspace, but its parent workspace manages gestures for it.
|
|
133
|
+
* @type {!WorkspaceSvg}
|
|
134
|
+
* @private
|
|
135
|
+
*/
|
|
136
|
+
this.creatorWorkspace_ = creatorWorkspace;
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Whether the pointer has at any point moved out of the drag radius.
|
|
140
|
+
* A gesture that exceeds the drag radius is a drag even if it ends exactly
|
|
141
|
+
* at its start point.
|
|
142
|
+
* @type {boolean}
|
|
143
|
+
* @private
|
|
144
|
+
*/
|
|
145
|
+
this.hasExceededDragRadius_ = false;
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Whether the workspace is currently being dragged.
|
|
149
|
+
* @type {boolean}
|
|
150
|
+
* @private
|
|
151
|
+
*/
|
|
152
|
+
this.isDraggingWorkspace_ = false;
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Whether the block is currently being dragged.
|
|
156
|
+
* @type {boolean}
|
|
157
|
+
* @private
|
|
158
|
+
*/
|
|
159
|
+
this.isDraggingBlock_ = false;
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Whether the bubble is currently being dragged.
|
|
163
|
+
* @type {boolean}
|
|
164
|
+
* @private
|
|
165
|
+
*/
|
|
166
|
+
this.isDraggingBubble_ = false;
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* The event that most recently updated this gesture.
|
|
170
|
+
* @type {!Event}
|
|
171
|
+
* @private
|
|
172
|
+
*/
|
|
173
|
+
this.mostRecentEvent_ = e;
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* A handle to use to unbind a mouse move listener at the end of a drag.
|
|
177
|
+
* Opaque data returned from Blockly.bindEventWithChecks_.
|
|
178
|
+
* @type {?browserEvents.Data}
|
|
179
|
+
* @protected
|
|
180
|
+
*/
|
|
181
|
+
this.onMoveWrapper_ = null;
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* A handle to use to unbind a mouse up listener at the end of a drag.
|
|
185
|
+
* Opaque data returned from Blockly.bindEventWithChecks_.
|
|
186
|
+
* @type {?browserEvents.Data}
|
|
187
|
+
* @protected
|
|
188
|
+
*/
|
|
189
|
+
this.onUpWrapper_ = null;
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* The object tracking a bubble drag, or null if none is in progress.
|
|
193
|
+
* @type {BubbleDragger}
|
|
194
|
+
* @private
|
|
195
|
+
*/
|
|
196
|
+
this.bubbleDragger_ = null;
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* The object tracking a block drag, or null if none is in progress.
|
|
200
|
+
* @type {?IBlockDragger}
|
|
201
|
+
* @private
|
|
202
|
+
*/
|
|
203
|
+
this.blockDragger_ = null;
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* The object tracking a workspace or flyout workspace drag, or null if none
|
|
207
|
+
* is in progress.
|
|
208
|
+
* @type {WorkspaceDragger}
|
|
209
|
+
* @private
|
|
210
|
+
*/
|
|
211
|
+
this.workspaceDragger_ = null;
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* The flyout a gesture started in, if any.
|
|
215
|
+
* @type {IFlyout}
|
|
216
|
+
* @private
|
|
217
|
+
*/
|
|
218
|
+
this.flyout_ = null;
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Boolean for sanity-checking that some code is only called once.
|
|
222
|
+
* @type {boolean}
|
|
223
|
+
* @private
|
|
224
|
+
*/
|
|
225
|
+
this.calledUpdateIsDragging_ = false;
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Boolean for sanity-checking that some code is only called once.
|
|
229
|
+
* @type {boolean}
|
|
230
|
+
* @private
|
|
231
|
+
*/
|
|
232
|
+
this.hasStarted_ = false;
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Boolean used internally to break a cycle in disposal.
|
|
236
|
+
* @type {boolean}
|
|
237
|
+
* @protected
|
|
238
|
+
*/
|
|
239
|
+
this.isEnding_ = false;
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Boolean used to indicate whether or not to heal the stack after
|
|
243
|
+
* disconnecting a block.
|
|
244
|
+
* @type {boolean}
|
|
245
|
+
* @private
|
|
246
|
+
*/
|
|
247
|
+
this.healStack_ = !internalConstants.DRAG_STACK;
|
|
248
|
+
}
|
|
80
249
|
|
|
81
250
|
/**
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
* @type {IBubble}
|
|
85
|
-
* @private
|
|
251
|
+
* Sever all links from this object.
|
|
252
|
+
* @package
|
|
86
253
|
*/
|
|
87
|
-
|
|
254
|
+
dispose() {
|
|
255
|
+
Touch.clearTouchIdentifier();
|
|
256
|
+
Tooltip.unblock();
|
|
257
|
+
// Clear the owner's reference to this gesture.
|
|
258
|
+
this.creatorWorkspace_.clearGesture();
|
|
259
|
+
|
|
260
|
+
if (this.onMoveWrapper_) {
|
|
261
|
+
browserEvents.unbind(this.onMoveWrapper_);
|
|
262
|
+
}
|
|
263
|
+
if (this.onUpWrapper_) {
|
|
264
|
+
browserEvents.unbind(this.onUpWrapper_);
|
|
265
|
+
}
|
|
88
266
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
267
|
+
if (this.blockDragger_) {
|
|
268
|
+
this.blockDragger_.dispose();
|
|
269
|
+
}
|
|
270
|
+
if (this.workspaceDragger_) {
|
|
271
|
+
this.workspaceDragger_.dispose();
|
|
272
|
+
}
|
|
273
|
+
if (this.bubbleDragger_) {
|
|
274
|
+
this.bubbleDragger_.dispose();
|
|
275
|
+
}
|
|
276
|
+
}
|
|
96
277
|
|
|
97
278
|
/**
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
* @type {BlockSvg}
|
|
279
|
+
* Update internal state based on an event.
|
|
280
|
+
* @param {!Event} e The most recent mouse or touch event.
|
|
101
281
|
* @private
|
|
102
282
|
*/
|
|
103
|
-
|
|
283
|
+
updateFromEvent_(e) {
|
|
284
|
+
const currentXY = new Coordinate(e.clientX, e.clientY);
|
|
285
|
+
const changed = this.updateDragDelta_(currentXY);
|
|
286
|
+
// Exceeded the drag radius for the first time.
|
|
287
|
+
if (changed) {
|
|
288
|
+
this.updateIsDragging_();
|
|
289
|
+
Touch.longStop();
|
|
290
|
+
}
|
|
291
|
+
this.mostRecentEvent_ = e;
|
|
292
|
+
}
|
|
104
293
|
|
|
105
294
|
/**
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
*
|
|
295
|
+
* DO MATH to set currentDragDeltaXY_ based on the most recent mouse position.
|
|
296
|
+
* @param {!Coordinate} currentXY The most recent mouse/pointer
|
|
297
|
+
* position, in pixel units, with (0, 0) at the window's top left corner.
|
|
298
|
+
* @return {boolean} True if the drag just exceeded the drag radius for the
|
|
299
|
+
* first time.
|
|
111
300
|
* @private
|
|
112
301
|
*/
|
|
113
|
-
|
|
302
|
+
updateDragDelta_(currentXY) {
|
|
303
|
+
this.currentDragDeltaXY_ = Coordinate.difference(
|
|
304
|
+
currentXY,
|
|
305
|
+
/** @type {!Coordinate} */ (this.mouseDownXY_));
|
|
114
306
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
* workspaces on a page; this is more accurate than using
|
|
118
|
-
* Blockly.common.getMainWorkspace().
|
|
119
|
-
* @type {WorkspaceSvg}
|
|
120
|
-
* @protected
|
|
121
|
-
*/
|
|
122
|
-
this.startWorkspace_ = null;
|
|
307
|
+
if (!this.hasExceededDragRadius_) {
|
|
308
|
+
const currentDragDelta = Coordinate.magnitude(this.currentDragDeltaXY_);
|
|
123
309
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
* This may be different from the start workspace. For instance, a flyout is
|
|
128
|
-
* a workspace, but its parent workspace manages gestures for it.
|
|
129
|
-
* @type {!WorkspaceSvg}
|
|
130
|
-
* @private
|
|
131
|
-
*/
|
|
132
|
-
this.creatorWorkspace_ = creatorWorkspace;
|
|
310
|
+
// The flyout has a different drag radius from the rest of Blockly.
|
|
311
|
+
const limitRadius =
|
|
312
|
+
this.flyout_ ? config.flyoutDragRadius : config.dragRadius;
|
|
133
313
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
* @private
|
|
140
|
-
*/
|
|
141
|
-
this.hasExceededDragRadius_ = false;
|
|
314
|
+
this.hasExceededDragRadius_ = currentDragDelta > limitRadius;
|
|
315
|
+
return this.hasExceededDragRadius_;
|
|
316
|
+
}
|
|
317
|
+
return false;
|
|
318
|
+
}
|
|
142
319
|
|
|
143
320
|
/**
|
|
144
|
-
*
|
|
145
|
-
*
|
|
321
|
+
* Update this gesture to record whether a block is being dragged from the
|
|
322
|
+
* flyout.
|
|
323
|
+
* This function should be called on a mouse/touch move event the first time
|
|
324
|
+
* the drag radius is exceeded. It should be called no more than once per
|
|
325
|
+
* gesture. If a block should be dragged from the flyout this function creates
|
|
326
|
+
* the new block on the main workspace and updates targetBlock_ and
|
|
327
|
+
* startWorkspace_.
|
|
328
|
+
* @return {boolean} True if a block is being dragged from the flyout.
|
|
146
329
|
* @private
|
|
147
330
|
*/
|
|
148
|
-
|
|
331
|
+
updateIsDraggingFromFlyout_() {
|
|
332
|
+
if (!this.targetBlock_) {
|
|
333
|
+
return false;
|
|
334
|
+
}
|
|
335
|
+
if (!this.flyout_.isBlockCreatable_(this.targetBlock_)) {
|
|
336
|
+
return false;
|
|
337
|
+
}
|
|
338
|
+
if (!this.flyout_.isScrollable() ||
|
|
339
|
+
this.flyout_.isDragTowardWorkspace(this.currentDragDeltaXY_)) {
|
|
340
|
+
this.startWorkspace_ = this.flyout_.targetWorkspace;
|
|
341
|
+
this.startWorkspace_.updateScreenCalculationsIfScrolled();
|
|
342
|
+
// Start the event group now, so that the same event group is used for
|
|
343
|
+
// block creation and block dragging.
|
|
344
|
+
if (!eventUtils.getGroup()) {
|
|
345
|
+
eventUtils.setGroup(true);
|
|
346
|
+
}
|
|
347
|
+
// The start block is no longer relevant, because this is a drag.
|
|
348
|
+
this.startBlock_ = null;
|
|
349
|
+
this.targetBlock_ = this.flyout_.createBlock(this.targetBlock_);
|
|
350
|
+
this.targetBlock_.select();
|
|
351
|
+
return true;
|
|
352
|
+
}
|
|
353
|
+
return false;
|
|
354
|
+
}
|
|
149
355
|
|
|
150
356
|
/**
|
|
151
|
-
*
|
|
152
|
-
*
|
|
357
|
+
* Update this gesture to record whether a bubble is being dragged.
|
|
358
|
+
* This function should be called on a mouse/touch move event the first time
|
|
359
|
+
* the drag radius is exceeded. It should be called no more than once per
|
|
360
|
+
* gesture. If a bubble should be dragged this function creates the necessary
|
|
361
|
+
* BubbleDragger and starts the drag.
|
|
362
|
+
* @return {boolean} True if a bubble is being dragged.
|
|
153
363
|
* @private
|
|
154
364
|
*/
|
|
155
|
-
|
|
365
|
+
updateIsDraggingBubble_() {
|
|
366
|
+
if (!this.startBubble_) {
|
|
367
|
+
return false;
|
|
368
|
+
}
|
|
156
369
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
*/
|
|
162
|
-
this.isDraggingBubble_ = false;
|
|
370
|
+
this.isDraggingBubble_ = true;
|
|
371
|
+
this.startDraggingBubble_();
|
|
372
|
+
return true;
|
|
373
|
+
}
|
|
163
374
|
|
|
164
375
|
/**
|
|
165
|
-
*
|
|
166
|
-
*
|
|
376
|
+
* Update this gesture to record whether a block is being dragged.
|
|
377
|
+
* This function should be called on a mouse/touch move event the first time
|
|
378
|
+
* the drag radius is exceeded. It should be called no more than once per
|
|
379
|
+
* gesture. If a block should be dragged, either from the flyout or in the
|
|
380
|
+
* workspace, this function creates the necessary BlockDragger and starts the
|
|
381
|
+
* drag.
|
|
382
|
+
* @return {boolean} True if a block is being dragged.
|
|
167
383
|
* @private
|
|
168
384
|
*/
|
|
169
|
-
|
|
385
|
+
updateIsDraggingBlock_() {
|
|
386
|
+
if (!this.targetBlock_) {
|
|
387
|
+
return false;
|
|
388
|
+
}
|
|
170
389
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
*/
|
|
177
|
-
this.onMoveWrapper_ = null;
|
|
390
|
+
if (this.flyout_) {
|
|
391
|
+
this.isDraggingBlock_ = this.updateIsDraggingFromFlyout_();
|
|
392
|
+
} else if (this.targetBlock_.isMovable()) {
|
|
393
|
+
this.isDraggingBlock_ = true;
|
|
394
|
+
}
|
|
178
395
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
this.onUpWrapper_ = null;
|
|
396
|
+
if (this.isDraggingBlock_) {
|
|
397
|
+
this.startDraggingBlock_();
|
|
398
|
+
return true;
|
|
399
|
+
}
|
|
400
|
+
return false;
|
|
401
|
+
}
|
|
186
402
|
|
|
187
403
|
/**
|
|
188
|
-
*
|
|
189
|
-
*
|
|
404
|
+
* Update this gesture to record whether a workspace is being dragged.
|
|
405
|
+
* This function should be called on a mouse/touch move event the first time
|
|
406
|
+
* the drag radius is exceeded. It should be called no more than once per
|
|
407
|
+
* gesture. If a workspace is being dragged this function creates the
|
|
408
|
+
* necessary WorkspaceDragger and starts the drag.
|
|
190
409
|
* @private
|
|
191
410
|
*/
|
|
192
|
-
|
|
411
|
+
updateIsDraggingWorkspace_() {
|
|
412
|
+
const wsMovable = this.flyout_ ?
|
|
413
|
+
this.flyout_.isScrollable() :
|
|
414
|
+
this.startWorkspace_ && this.startWorkspace_.isDraggable();
|
|
193
415
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
* @private
|
|
198
|
-
*/
|
|
199
|
-
this.blockDragger_ = null;
|
|
416
|
+
if (!wsMovable) {
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
200
419
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
* is in progress.
|
|
204
|
-
* @type {WorkspaceDragger}
|
|
205
|
-
* @private
|
|
206
|
-
*/
|
|
207
|
-
this.workspaceDragger_ = null;
|
|
420
|
+
this.workspaceDragger_ = new WorkspaceDragger(
|
|
421
|
+
/** @type {!WorkspaceSvg} */ (this.startWorkspace_));
|
|
208
422
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
* @private
|
|
213
|
-
*/
|
|
214
|
-
this.flyout_ = null;
|
|
423
|
+
this.isDraggingWorkspace_ = true;
|
|
424
|
+
this.workspaceDragger_.startDrag();
|
|
425
|
+
}
|
|
215
426
|
|
|
216
427
|
/**
|
|
217
|
-
*
|
|
218
|
-
*
|
|
428
|
+
* Update this gesture to record whether anything is being dragged.
|
|
429
|
+
* This function should be called on a mouse/touch move event the first time
|
|
430
|
+
* the drag radius is exceeded. It should be called no more than once per
|
|
431
|
+
* gesture.
|
|
219
432
|
* @private
|
|
220
433
|
*/
|
|
221
|
-
|
|
434
|
+
updateIsDragging_() {
|
|
435
|
+
// Sanity check.
|
|
436
|
+
if (this.calledUpdateIsDragging_) {
|
|
437
|
+
throw Error('updateIsDragging_ should only be called once per gesture.');
|
|
438
|
+
}
|
|
439
|
+
this.calledUpdateIsDragging_ = true;
|
|
222
440
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
441
|
+
// First check if it was a bubble drag. Bubbles always sit on top of
|
|
442
|
+
// blocks.
|
|
443
|
+
if (this.updateIsDraggingBubble_()) {
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
446
|
+
// Then check if it was a block drag.
|
|
447
|
+
if (this.updateIsDraggingBlock_()) {
|
|
448
|
+
return;
|
|
449
|
+
}
|
|
450
|
+
// Then check if it's a workspace drag.
|
|
451
|
+
this.updateIsDraggingWorkspace_();
|
|
452
|
+
}
|
|
229
453
|
|
|
230
454
|
/**
|
|
231
|
-
*
|
|
232
|
-
* @
|
|
233
|
-
* @protected
|
|
455
|
+
* Create a block dragger and start dragging the selected block.
|
|
456
|
+
* @private
|
|
234
457
|
*/
|
|
235
|
-
|
|
458
|
+
startDraggingBlock_() {
|
|
459
|
+
const BlockDraggerClass = registry.getClassFromOptions(
|
|
460
|
+
registry.Type.BLOCK_DRAGGER, this.creatorWorkspace_.options, true);
|
|
461
|
+
|
|
462
|
+
this.blockDragger_ = new BlockDraggerClass(
|
|
463
|
+
/** @type {!BlockSvg} */ (this.targetBlock_),
|
|
464
|
+
/** @type {!WorkspaceSvg} */ (this.startWorkspace_));
|
|
465
|
+
this.blockDragger_.startDrag(this.currentDragDeltaXY_, this.healStack_);
|
|
466
|
+
this.blockDragger_.drag(this.mostRecentEvent_, this.currentDragDeltaXY_);
|
|
467
|
+
}
|
|
236
468
|
|
|
469
|
+
// TODO (fenichel): Possibly combine this and startDraggingBlock_.
|
|
237
470
|
/**
|
|
238
|
-
*
|
|
239
|
-
* disconnecting a block.
|
|
240
|
-
* @type {boolean}
|
|
471
|
+
* Create a bubble dragger and start dragging the selected bubble.
|
|
241
472
|
* @private
|
|
242
473
|
*/
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
/**
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
Gesture.prototype.dispose = function() {
|
|
251
|
-
Touch.clearTouchIdentifier();
|
|
252
|
-
Tooltip.unblock();
|
|
253
|
-
// Clear the owner's reference to this gesture.
|
|
254
|
-
this.creatorWorkspace_.clearGesture();
|
|
255
|
-
|
|
256
|
-
if (this.onMoveWrapper_) {
|
|
257
|
-
browserEvents.unbind(this.onMoveWrapper_);
|
|
258
|
-
}
|
|
259
|
-
if (this.onUpWrapper_) {
|
|
260
|
-
browserEvents.unbind(this.onUpWrapper_);
|
|
474
|
+
startDraggingBubble_() {
|
|
475
|
+
this.bubbleDragger_ = new BubbleDragger(
|
|
476
|
+
/** @type {!IBubble} */ (this.startBubble_),
|
|
477
|
+
/** @type {!WorkspaceSvg} */ (this.startWorkspace_));
|
|
478
|
+
this.bubbleDragger_.startBubbleDrag();
|
|
479
|
+
this.bubbleDragger_.dragBubble(
|
|
480
|
+
this.mostRecentEvent_, this.currentDragDeltaXY_);
|
|
261
481
|
}
|
|
262
482
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
483
|
+
/**
|
|
484
|
+
* Start a gesture: update the workspace to indicate that a gesture is in
|
|
485
|
+
* progress and bind mousemove and mouseup handlers.
|
|
486
|
+
* @param {!Event} e A mouse down or touch start event.
|
|
487
|
+
* @package
|
|
488
|
+
*/
|
|
489
|
+
doStart(e) {
|
|
490
|
+
if (browserEvents.isTargetInput(e)) {
|
|
491
|
+
this.cancel();
|
|
492
|
+
return;
|
|
493
|
+
}
|
|
494
|
+
this.hasStarted_ = true;
|
|
273
495
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
const changed = this.updateDragDelta_(currentXY);
|
|
282
|
-
// Exceeded the drag radius for the first time.
|
|
283
|
-
if (changed) {
|
|
284
|
-
this.updateIsDragging_();
|
|
285
|
-
Touch.longStop();
|
|
286
|
-
}
|
|
287
|
-
this.mostRecentEvent_ = e;
|
|
288
|
-
};
|
|
496
|
+
blockAnimations.disconnectUiStop();
|
|
497
|
+
this.startWorkspace_.updateScreenCalculationsIfScrolled();
|
|
498
|
+
if (this.startWorkspace_.isMutator) {
|
|
499
|
+
// Mutator's coordinate system could be out of date because the bubble was
|
|
500
|
+
// dragged, the block was moved, the parent workspace zoomed, etc.
|
|
501
|
+
this.startWorkspace_.resize();
|
|
502
|
+
}
|
|
289
503
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
* position, in pixel units, with (0, 0) at the window's top left corner.
|
|
294
|
-
* @return {boolean} True if the drag just exceeded the drag radius for the
|
|
295
|
-
* first time.
|
|
296
|
-
* @private
|
|
297
|
-
*/
|
|
298
|
-
Gesture.prototype.updateDragDelta_ = function(currentXY) {
|
|
299
|
-
this.currentDragDeltaXY_ = Coordinate.difference(
|
|
300
|
-
currentXY,
|
|
301
|
-
/** @type {!Coordinate} */ (this.mouseDownXY_));
|
|
504
|
+
// Hide chaff also hides the flyout, so don't do it if the click is in a
|
|
505
|
+
// flyout.
|
|
506
|
+
this.startWorkspace_.hideChaff(!!this.flyout_);
|
|
302
507
|
|
|
303
|
-
|
|
304
|
-
|
|
508
|
+
this.startWorkspace_.markFocused();
|
|
509
|
+
this.mostRecentEvent_ = e;
|
|
305
510
|
|
|
306
|
-
|
|
307
|
-
const limitRadius = this.flyout_ ? internalConstants.FLYOUT_DRAG_RADIUS :
|
|
308
|
-
internalConstants.DRAG_RADIUS;
|
|
511
|
+
Tooltip.block();
|
|
309
512
|
|
|
310
|
-
this.
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
return false;
|
|
314
|
-
};
|
|
513
|
+
if (this.targetBlock_) {
|
|
514
|
+
this.targetBlock_.select();
|
|
515
|
+
}
|
|
315
516
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
* This function should be called on a mouse/touch move event the first time the
|
|
320
|
-
* drag radius is exceeded. It should be called no more than once per gesture.
|
|
321
|
-
* If a block should be dragged from the flyout this function creates the new
|
|
322
|
-
* block on the main workspace and updates targetBlock_ and startWorkspace_.
|
|
323
|
-
* @return {boolean} True if a block is being dragged from the flyout.
|
|
324
|
-
* @private
|
|
325
|
-
*/
|
|
326
|
-
Gesture.prototype.updateIsDraggingFromFlyout_ = function() {
|
|
327
|
-
if (!this.targetBlock_) {
|
|
328
|
-
return false;
|
|
329
|
-
}
|
|
330
|
-
if (!this.flyout_.isBlockCreatable_(this.targetBlock_)) {
|
|
331
|
-
return false;
|
|
332
|
-
}
|
|
333
|
-
if (!this.flyout_.isScrollable() ||
|
|
334
|
-
this.flyout_.isDragTowardWorkspace(this.currentDragDeltaXY_)) {
|
|
335
|
-
this.startWorkspace_ = this.flyout_.targetWorkspace;
|
|
336
|
-
this.startWorkspace_.updateScreenCalculationsIfScrolled();
|
|
337
|
-
// Start the event group now, so that the same event group is used for block
|
|
338
|
-
// creation and block dragging.
|
|
339
|
-
if (!eventUtils.getGroup()) {
|
|
340
|
-
eventUtils.setGroup(true);
|
|
517
|
+
if (browserEvents.isRightButton(e)) {
|
|
518
|
+
this.handleRightClick(e);
|
|
519
|
+
return;
|
|
341
520
|
}
|
|
342
|
-
// The start block is no longer relevant, because this is a drag.
|
|
343
|
-
this.startBlock_ = null;
|
|
344
|
-
this.targetBlock_ = this.flyout_.createBlock(this.targetBlock_);
|
|
345
|
-
this.targetBlock_.select();
|
|
346
|
-
return true;
|
|
347
|
-
}
|
|
348
|
-
return false;
|
|
349
|
-
};
|
|
350
521
|
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
* BubbleDragger and starts the drag.
|
|
357
|
-
* @return {boolean} True if a bubble is being dragged.
|
|
358
|
-
* @private
|
|
359
|
-
*/
|
|
360
|
-
Gesture.prototype.updateIsDraggingBubble_ = function() {
|
|
361
|
-
if (!this.startBubble_) {
|
|
362
|
-
return false;
|
|
363
|
-
}
|
|
522
|
+
if ((e.type.toLowerCase() === 'touchstart' ||
|
|
523
|
+
e.type.toLowerCase() === 'pointerdown') &&
|
|
524
|
+
e.pointerType !== 'mouse') {
|
|
525
|
+
Touch.longStart(e, this);
|
|
526
|
+
}
|
|
364
527
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
return true;
|
|
368
|
-
};
|
|
528
|
+
this.mouseDownXY_ = new Coordinate(e.clientX, e.clientY);
|
|
529
|
+
this.healStack_ = e.altKey || e.ctrlKey || e.metaKey;
|
|
369
530
|
|
|
370
|
-
|
|
371
|
-
* Update this gesture to record whether a block is being dragged.
|
|
372
|
-
* This function should be called on a mouse/touch move event the first time the
|
|
373
|
-
* drag radius is exceeded. It should be called no more than once per gesture.
|
|
374
|
-
* If a block should be dragged, either from the flyout or in the workspace,
|
|
375
|
-
* this function creates the necessary BlockDragger and starts the drag.
|
|
376
|
-
* @return {boolean} True if a block is being dragged.
|
|
377
|
-
* @private
|
|
378
|
-
*/
|
|
379
|
-
Gesture.prototype.updateIsDraggingBlock_ = function() {
|
|
380
|
-
if (!this.targetBlock_) {
|
|
381
|
-
return false;
|
|
531
|
+
this.bindMouseEvents(e);
|
|
382
532
|
}
|
|
383
533
|
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
534
|
+
/**
|
|
535
|
+
* Bind gesture events.
|
|
536
|
+
* @param {!Event} e A mouse down or touch start event.
|
|
537
|
+
* @package
|
|
538
|
+
*/
|
|
539
|
+
bindMouseEvents(e) {
|
|
540
|
+
this.onMoveWrapper_ = browserEvents.conditionalBind(
|
|
541
|
+
document, 'mousemove', null, this.handleMove.bind(this));
|
|
542
|
+
this.onUpWrapper_ = browserEvents.conditionalBind(
|
|
543
|
+
document, 'mouseup', null, this.handleUp.bind(this));
|
|
544
|
+
|
|
545
|
+
e.preventDefault();
|
|
546
|
+
e.stopPropagation();
|
|
388
547
|
}
|
|
389
548
|
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
549
|
+
/**
|
|
550
|
+
* Handle a mouse move or touch move event.
|
|
551
|
+
* @param {!Event} e A mouse move or touch move event.
|
|
552
|
+
* @package
|
|
553
|
+
*/
|
|
554
|
+
handleMove(e) {
|
|
555
|
+
this.updateFromEvent_(e);
|
|
556
|
+
if (this.isDraggingWorkspace_) {
|
|
557
|
+
this.workspaceDragger_.drag(this.currentDragDeltaXY_);
|
|
558
|
+
} else if (this.isDraggingBlock_) {
|
|
559
|
+
this.blockDragger_.drag(this.mostRecentEvent_, this.currentDragDeltaXY_);
|
|
560
|
+
} else if (this.isDraggingBubble_) {
|
|
561
|
+
this.bubbleDragger_.dragBubble(
|
|
562
|
+
this.mostRecentEvent_, this.currentDragDeltaXY_);
|
|
563
|
+
}
|
|
564
|
+
e.preventDefault();
|
|
565
|
+
e.stopPropagation();
|
|
393
566
|
}
|
|
394
|
-
return false;
|
|
395
|
-
};
|
|
396
|
-
|
|
397
|
-
/**
|
|
398
|
-
* Update this gesture to record whether a workspace is being dragged.
|
|
399
|
-
* This function should be called on a mouse/touch move event the first time the
|
|
400
|
-
* drag radius is exceeded. It should be called no more than once per gesture.
|
|
401
|
-
* If a workspace is being dragged this function creates the necessary
|
|
402
|
-
* WorkspaceDragger and starts the drag.
|
|
403
|
-
* @private
|
|
404
|
-
*/
|
|
405
|
-
Gesture.prototype.updateIsDraggingWorkspace_ = function() {
|
|
406
|
-
const wsMovable = this.flyout_ ?
|
|
407
|
-
this.flyout_.isScrollable() :
|
|
408
|
-
this.startWorkspace_ && this.startWorkspace_.isDraggable();
|
|
409
567
|
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
568
|
+
/**
|
|
569
|
+
* Handle a mouse up or touch end event.
|
|
570
|
+
* @param {!Event} e A mouse up or touch end event.
|
|
571
|
+
* @package
|
|
572
|
+
*/
|
|
573
|
+
handleUp(e) {
|
|
574
|
+
this.updateFromEvent_(e);
|
|
575
|
+
Touch.longStop();
|
|
413
576
|
|
|
414
|
-
|
|
415
|
-
|
|
577
|
+
if (this.isEnding_) {
|
|
578
|
+
console.log('Trying to end a gesture recursively.');
|
|
579
|
+
return;
|
|
580
|
+
}
|
|
581
|
+
this.isEnding_ = true;
|
|
582
|
+
// The ordering of these checks is important: drags have higher priority
|
|
583
|
+
// than clicks. Fields have higher priority than blocks; blocks have higher
|
|
584
|
+
// priority than workspaces.
|
|
585
|
+
// The ordering within drags does not matter, because the three types of
|
|
586
|
+
// dragging are exclusive.
|
|
587
|
+
if (this.isDraggingBubble_) {
|
|
588
|
+
this.bubbleDragger_.endBubbleDrag(e, this.currentDragDeltaXY_);
|
|
589
|
+
} else if (this.isDraggingBlock_) {
|
|
590
|
+
this.blockDragger_.endDrag(e, this.currentDragDeltaXY_);
|
|
591
|
+
} else if (this.isDraggingWorkspace_) {
|
|
592
|
+
this.workspaceDragger_.endDrag(this.currentDragDeltaXY_);
|
|
593
|
+
} else if (this.isBubbleClick_()) {
|
|
594
|
+
// Bubbles are in front of all fields and blocks.
|
|
595
|
+
this.doBubbleClick_();
|
|
596
|
+
} else if (this.isFieldClick_()) {
|
|
597
|
+
this.doFieldClick_();
|
|
598
|
+
} else if (this.isBlockClick_()) {
|
|
599
|
+
this.doBlockClick_();
|
|
600
|
+
} else if (this.isWorkspaceClick_()) {
|
|
601
|
+
this.doWorkspaceClick_(e);
|
|
602
|
+
}
|
|
416
603
|
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
};
|
|
604
|
+
e.preventDefault();
|
|
605
|
+
e.stopPropagation();
|
|
420
606
|
|
|
421
|
-
|
|
422
|
-
* Update this gesture to record whether anything is being dragged.
|
|
423
|
-
* This function should be called on a mouse/touch move event the first time the
|
|
424
|
-
* drag radius is exceeded. It should be called no more than once per gesture.
|
|
425
|
-
* @private
|
|
426
|
-
*/
|
|
427
|
-
Gesture.prototype.updateIsDragging_ = function() {
|
|
428
|
-
// Sanity check.
|
|
429
|
-
if (this.calledUpdateIsDragging_) {
|
|
430
|
-
throw Error('updateIsDragging_ should only be called once per gesture.');
|
|
607
|
+
this.dispose();
|
|
431
608
|
}
|
|
432
|
-
this.calledUpdateIsDragging_ = true;
|
|
433
609
|
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
610
|
+
/**
|
|
611
|
+
* Cancel an in-progress gesture. If a workspace or block drag is in
|
|
612
|
+
* progress, end the drag at the most recent location.
|
|
613
|
+
* @package
|
|
614
|
+
*/
|
|
615
|
+
cancel() {
|
|
616
|
+
// Disposing of a block cancels in-progress drags, but dragging to a delete
|
|
617
|
+
// area disposes of a block and leads to recursive disposal. Break that
|
|
618
|
+
// cycle.
|
|
619
|
+
if (this.isEnding_) {
|
|
620
|
+
return;
|
|
621
|
+
}
|
|
622
|
+
Touch.longStop();
|
|
623
|
+
if (this.isDraggingBubble_) {
|
|
624
|
+
this.bubbleDragger_.endBubbleDrag(
|
|
625
|
+
this.mostRecentEvent_, this.currentDragDeltaXY_);
|
|
626
|
+
} else if (this.isDraggingBlock_) {
|
|
627
|
+
this.blockDragger_.endDrag(
|
|
628
|
+
this.mostRecentEvent_, this.currentDragDeltaXY_);
|
|
629
|
+
} else if (this.isDraggingWorkspace_) {
|
|
630
|
+
this.workspaceDragger_.endDrag(this.currentDragDeltaXY_);
|
|
631
|
+
}
|
|
632
|
+
this.dispose();
|
|
441
633
|
}
|
|
442
|
-
// Then check if it's a workspace drag.
|
|
443
|
-
this.updateIsDraggingWorkspace_();
|
|
444
|
-
};
|
|
445
634
|
|
|
446
|
-
/**
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
635
|
+
/**
|
|
636
|
+
* Handle a real or faked right-click event by showing a context menu.
|
|
637
|
+
* @param {!Event} e A mouse move or touch move event.
|
|
638
|
+
* @package
|
|
639
|
+
*/
|
|
640
|
+
handleRightClick(e) {
|
|
641
|
+
if (this.targetBlock_) {
|
|
642
|
+
this.bringBlockToFront_();
|
|
643
|
+
this.targetBlock_.workspace.hideChaff(!!this.flyout_);
|
|
644
|
+
this.targetBlock_.showContextMenu(e);
|
|
645
|
+
} else if (this.startBubble_) {
|
|
646
|
+
this.startBubble_.showContextMenu(e);
|
|
647
|
+
} else if (this.startWorkspace_ && !this.flyout_) {
|
|
648
|
+
this.startWorkspace_.hideChaff();
|
|
649
|
+
this.startWorkspace_.showContextMenu(e);
|
|
650
|
+
}
|
|
453
651
|
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
this.blockDragger_.startDrag(this.currentDragDeltaXY_, this.healStack_);
|
|
458
|
-
this.blockDragger_.drag(this.mostRecentEvent_, this.currentDragDeltaXY_);
|
|
459
|
-
};
|
|
652
|
+
// TODO: Handle right-click on a bubble.
|
|
653
|
+
e.preventDefault();
|
|
654
|
+
e.stopPropagation();
|
|
460
655
|
|
|
461
|
-
|
|
462
|
-
* Create a bubble dragger and start dragging the selected bubble.
|
|
463
|
-
* @private
|
|
464
|
-
*/
|
|
465
|
-
// TODO (fenichel): Possibly combine this and startDraggingBlock_.
|
|
466
|
-
Gesture.prototype.startDraggingBubble_ = function() {
|
|
467
|
-
this.bubbleDragger_ = new BubbleDragger(
|
|
468
|
-
/** @type {!IBubble} */ (this.startBubble_),
|
|
469
|
-
/** @type {!WorkspaceSvg} */ (this.startWorkspace_));
|
|
470
|
-
this.bubbleDragger_.startBubbleDrag();
|
|
471
|
-
this.bubbleDragger_.dragBubble(
|
|
472
|
-
this.mostRecentEvent_, this.currentDragDeltaXY_);
|
|
473
|
-
};
|
|
474
|
-
/**
|
|
475
|
-
* Start a gesture: update the workspace to indicate that a gesture is in
|
|
476
|
-
* progress and bind mousemove and mouseup handlers.
|
|
477
|
-
* @param {!Event} e A mouse down or touch start event.
|
|
478
|
-
* @package
|
|
479
|
-
*/
|
|
480
|
-
Gesture.prototype.doStart = function(e) {
|
|
481
|
-
if (browserEvents.isTargetInput(e)) {
|
|
482
|
-
this.cancel();
|
|
483
|
-
return;
|
|
656
|
+
this.dispose();
|
|
484
657
|
}
|
|
485
|
-
this.hasStarted_ = true;
|
|
486
658
|
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
659
|
+
/**
|
|
660
|
+
* Handle a mousedown/touchstart event on a workspace.
|
|
661
|
+
* @param {!Event} e A mouse down or touch start event.
|
|
662
|
+
* @param {!WorkspaceSvg} ws The workspace the event hit.
|
|
663
|
+
* @package
|
|
664
|
+
*/
|
|
665
|
+
handleWsStart(e, ws) {
|
|
666
|
+
if (this.hasStarted_) {
|
|
667
|
+
throw Error(
|
|
668
|
+
'Tried to call gesture.handleWsStart, ' +
|
|
669
|
+
'but the gesture had already been started.');
|
|
670
|
+
}
|
|
671
|
+
this.setStartWorkspace_(ws);
|
|
672
|
+
this.mostRecentEvent_ = e;
|
|
673
|
+
this.doStart(e);
|
|
493
674
|
}
|
|
494
675
|
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
if (this.targetBlock_) {
|
|
505
|
-
this.targetBlock_.select();
|
|
676
|
+
/**
|
|
677
|
+
* Fires a workspace click event.
|
|
678
|
+
* @param {!WorkspaceSvg} ws The workspace that a user clicks on.
|
|
679
|
+
* @private
|
|
680
|
+
*/
|
|
681
|
+
fireWorkspaceClick_(ws) {
|
|
682
|
+
eventUtils.fire(
|
|
683
|
+
new (eventUtils.get(eventUtils.CLICK))(null, ws.id, 'workspace'));
|
|
506
684
|
}
|
|
507
685
|
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
686
|
+
/**
|
|
687
|
+
* Handle a mousedown/touchstart event on a flyout.
|
|
688
|
+
* @param {!Event} e A mouse down or touch start event.
|
|
689
|
+
* @param {!IFlyout} flyout The flyout the event hit.
|
|
690
|
+
* @package
|
|
691
|
+
*/
|
|
692
|
+
handleFlyoutStart(e, flyout) {
|
|
693
|
+
if (this.hasStarted_) {
|
|
694
|
+
throw Error(
|
|
695
|
+
'Tried to call gesture.handleFlyoutStart, ' +
|
|
696
|
+
'but the gesture had already been started.');
|
|
697
|
+
}
|
|
698
|
+
this.setStartFlyout_(flyout);
|
|
699
|
+
this.handleWsStart(e, flyout.getWorkspace());
|
|
511
700
|
}
|
|
512
701
|
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
702
|
+
/**
|
|
703
|
+
* Handle a mousedown/touchstart event on a block.
|
|
704
|
+
* @param {!Event} e A mouse down or touch start event.
|
|
705
|
+
* @param {!BlockSvg} block The block the event hit.
|
|
706
|
+
* @package
|
|
707
|
+
*/
|
|
708
|
+
handleBlockStart(e, block) {
|
|
709
|
+
if (this.hasStarted_) {
|
|
710
|
+
throw Error(
|
|
711
|
+
'Tried to call gesture.handleBlockStart, ' +
|
|
712
|
+
'but the gesture had already been started.');
|
|
713
|
+
}
|
|
714
|
+
this.setStartBlock(block);
|
|
715
|
+
this.mostRecentEvent_ = e;
|
|
517
716
|
}
|
|
518
717
|
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
this.onUpWrapper_ = browserEvents.conditionalBind(
|
|
534
|
-
document, 'mouseup', null, this.handleUp.bind(this));
|
|
535
|
-
|
|
536
|
-
e.preventDefault();
|
|
537
|
-
e.stopPropagation();
|
|
538
|
-
};
|
|
539
|
-
|
|
540
|
-
/**
|
|
541
|
-
* Handle a mouse move or touch move event.
|
|
542
|
-
* @param {!Event} e A mouse move or touch move event.
|
|
543
|
-
* @package
|
|
544
|
-
*/
|
|
545
|
-
Gesture.prototype.handleMove = function(e) {
|
|
546
|
-
this.updateFromEvent_(e);
|
|
547
|
-
if (this.isDraggingWorkspace_) {
|
|
548
|
-
this.workspaceDragger_.drag(this.currentDragDeltaXY_);
|
|
549
|
-
} else if (this.isDraggingBlock_) {
|
|
550
|
-
this.blockDragger_.drag(this.mostRecentEvent_, this.currentDragDeltaXY_);
|
|
551
|
-
} else if (this.isDraggingBubble_) {
|
|
552
|
-
this.bubbleDragger_.dragBubble(
|
|
553
|
-
this.mostRecentEvent_, this.currentDragDeltaXY_);
|
|
718
|
+
/**
|
|
719
|
+
* Handle a mousedown/touchstart event on a bubble.
|
|
720
|
+
* @param {!Event} e A mouse down or touch start event.
|
|
721
|
+
* @param {!IBubble} bubble The bubble the event hit.
|
|
722
|
+
* @package
|
|
723
|
+
*/
|
|
724
|
+
handleBubbleStart(e, bubble) {
|
|
725
|
+
if (this.hasStarted_) {
|
|
726
|
+
throw Error(
|
|
727
|
+
'Tried to call gesture.handleBubbleStart, ' +
|
|
728
|
+
'but the gesture had already been started.');
|
|
729
|
+
}
|
|
730
|
+
this.setStartBubble(bubble);
|
|
731
|
+
this.mostRecentEvent_ = e;
|
|
554
732
|
}
|
|
555
|
-
e.preventDefault();
|
|
556
|
-
e.stopPropagation();
|
|
557
|
-
};
|
|
558
733
|
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
* @package
|
|
563
|
-
*/
|
|
564
|
-
Gesture.prototype.handleUp = function(e) {
|
|
565
|
-
this.updateFromEvent_(e);
|
|
566
|
-
Touch.longStop();
|
|
567
|
-
|
|
568
|
-
if (this.isEnding_) {
|
|
569
|
-
console.log('Trying to end a gesture recursively.');
|
|
570
|
-
return;
|
|
571
|
-
}
|
|
572
|
-
this.isEnding_ = true;
|
|
573
|
-
// The ordering of these checks is important: drags have higher priority than
|
|
574
|
-
// clicks. Fields have higher priority than blocks; blocks have higher
|
|
575
|
-
// priority than workspaces.
|
|
576
|
-
// The ordering within drags does not matter, because the three types of
|
|
577
|
-
// dragging are exclusive.
|
|
578
|
-
if (this.isDraggingBubble_) {
|
|
579
|
-
this.bubbleDragger_.endBubbleDrag(e, this.currentDragDeltaXY_);
|
|
580
|
-
} else if (this.isDraggingBlock_) {
|
|
581
|
-
this.blockDragger_.endDrag(e, this.currentDragDeltaXY_);
|
|
582
|
-
} else if (this.isDraggingWorkspace_) {
|
|
583
|
-
this.workspaceDragger_.endDrag(this.currentDragDeltaXY_);
|
|
584
|
-
} else if (this.isBubbleClick_()) {
|
|
585
|
-
// Bubbles are in front of all fields and blocks.
|
|
586
|
-
this.doBubbleClick_();
|
|
587
|
-
} else if (this.isFieldClick_()) {
|
|
588
|
-
this.doFieldClick_();
|
|
589
|
-
} else if (this.isBlockClick_()) {
|
|
590
|
-
this.doBlockClick_();
|
|
591
|
-
} else if (this.isWorkspaceClick_()) {
|
|
592
|
-
this.doWorkspaceClick_(e);
|
|
593
|
-
}
|
|
594
|
-
|
|
595
|
-
e.preventDefault();
|
|
596
|
-
e.stopPropagation();
|
|
597
|
-
|
|
598
|
-
this.dispose();
|
|
599
|
-
};
|
|
734
|
+
/* Begin functions defining what actions to take to execute clicks on each
|
|
735
|
+
* type of target. Any developer wanting to add behaviour on clicks should
|
|
736
|
+
* modify only this code. */
|
|
600
737
|
|
|
601
|
-
/**
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
if (this.isEnding_) {
|
|
610
|
-
return;
|
|
611
|
-
}
|
|
612
|
-
Touch.longStop();
|
|
613
|
-
if (this.isDraggingBubble_) {
|
|
614
|
-
this.bubbleDragger_.endBubbleDrag(
|
|
615
|
-
this.mostRecentEvent_, this.currentDragDeltaXY_);
|
|
616
|
-
} else if (this.isDraggingBlock_) {
|
|
617
|
-
this.blockDragger_.endDrag(this.mostRecentEvent_, this.currentDragDeltaXY_);
|
|
618
|
-
} else if (this.isDraggingWorkspace_) {
|
|
619
|
-
this.workspaceDragger_.endDrag(this.currentDragDeltaXY_);
|
|
738
|
+
/**
|
|
739
|
+
* Execute a bubble click.
|
|
740
|
+
* @private
|
|
741
|
+
*/
|
|
742
|
+
doBubbleClick_() {
|
|
743
|
+
// TODO (#1673): Consistent handling of single clicks.
|
|
744
|
+
this.startBubble_.setFocus && this.startBubble_.setFocus();
|
|
745
|
+
this.startBubble_.select && this.startBubble_.select();
|
|
620
746
|
}
|
|
621
|
-
this.dispose();
|
|
622
|
-
};
|
|
623
747
|
|
|
624
|
-
/**
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
if (this.targetBlock_) {
|
|
748
|
+
/**
|
|
749
|
+
* Execute a field click.
|
|
750
|
+
* @private
|
|
751
|
+
*/
|
|
752
|
+
doFieldClick_() {
|
|
753
|
+
this.startField_.showEditor(this.mostRecentEvent_);
|
|
631
754
|
this.bringBlockToFront_();
|
|
632
|
-
this.targetBlock_.workspace.hideChaff(!!this.flyout_);
|
|
633
|
-
this.targetBlock_.showContextMenu(e);
|
|
634
|
-
} else if (this.startBubble_) {
|
|
635
|
-
this.startBubble_.showContextMenu(e);
|
|
636
|
-
} else if (this.startWorkspace_ && !this.flyout_) {
|
|
637
|
-
this.startWorkspace_.hideChaff();
|
|
638
|
-
this.startWorkspace_.showContextMenu(e);
|
|
639
|
-
}
|
|
640
|
-
|
|
641
|
-
// TODO: Handle right-click on a bubble.
|
|
642
|
-
e.preventDefault();
|
|
643
|
-
e.stopPropagation();
|
|
644
|
-
|
|
645
|
-
this.dispose();
|
|
646
|
-
};
|
|
647
|
-
|
|
648
|
-
/**
|
|
649
|
-
* Handle a mousedown/touchstart event on a workspace.
|
|
650
|
-
* @param {!Event} e A mouse down or touch start event.
|
|
651
|
-
* @param {!WorkspaceSvg} ws The workspace the event hit.
|
|
652
|
-
* @package
|
|
653
|
-
*/
|
|
654
|
-
Gesture.prototype.handleWsStart = function(e, ws) {
|
|
655
|
-
if (this.hasStarted_) {
|
|
656
|
-
throw Error(
|
|
657
|
-
'Tried to call gesture.handleWsStart, ' +
|
|
658
|
-
'but the gesture had already been started.');
|
|
659
|
-
}
|
|
660
|
-
this.setStartWorkspace_(ws);
|
|
661
|
-
this.mostRecentEvent_ = e;
|
|
662
|
-
this.doStart(e);
|
|
663
|
-
};
|
|
664
|
-
|
|
665
|
-
/**
|
|
666
|
-
* Fires a workspace click event.
|
|
667
|
-
* @param {!WorkspaceSvg} ws The workspace that a user clicks on.
|
|
668
|
-
* @private
|
|
669
|
-
*/
|
|
670
|
-
Gesture.prototype.fireWorkspaceClick_ = function(ws) {
|
|
671
|
-
eventUtils.fire(
|
|
672
|
-
new (eventUtils.get(eventUtils.CLICK))(null, ws.id, 'workspace'));
|
|
673
|
-
};
|
|
674
|
-
|
|
675
|
-
/**
|
|
676
|
-
* Handle a mousedown/touchstart event on a flyout.
|
|
677
|
-
* @param {!Event} e A mouse down or touch start event.
|
|
678
|
-
* @param {!IFlyout} flyout The flyout the event hit.
|
|
679
|
-
* @package
|
|
680
|
-
*/
|
|
681
|
-
Gesture.prototype.handleFlyoutStart = function(e, flyout) {
|
|
682
|
-
if (this.hasStarted_) {
|
|
683
|
-
throw Error(
|
|
684
|
-
'Tried to call gesture.handleFlyoutStart, ' +
|
|
685
|
-
'but the gesture had already been started.');
|
|
686
755
|
}
|
|
687
|
-
this.setStartFlyout_(flyout);
|
|
688
|
-
this.handleWsStart(e, flyout.getWorkspace());
|
|
689
|
-
};
|
|
690
756
|
|
|
691
|
-
/**
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
757
|
+
/**
|
|
758
|
+
* Execute a block click.
|
|
759
|
+
* @private
|
|
760
|
+
*/
|
|
761
|
+
doBlockClick_() {
|
|
762
|
+
// Block click in an autoclosing flyout.
|
|
763
|
+
if (this.flyout_ && this.flyout_.autoClose) {
|
|
764
|
+
if (this.targetBlock_.isEnabled()) {
|
|
765
|
+
if (!eventUtils.getGroup()) {
|
|
766
|
+
eventUtils.setGroup(true);
|
|
767
|
+
}
|
|
768
|
+
const newBlock = this.flyout_.createBlock(this.targetBlock_);
|
|
769
|
+
newBlock.scheduleSnapAndBump();
|
|
770
|
+
}
|
|
771
|
+
} else {
|
|
772
|
+
// Clicks events are on the start block, even if it was a shadow.
|
|
773
|
+
const event = new (eventUtils.get(eventUtils.CLICK))(
|
|
774
|
+
this.startBlock_, this.startWorkspace_.id, 'block');
|
|
775
|
+
eventUtils.fire(event);
|
|
776
|
+
}
|
|
777
|
+
this.bringBlockToFront_();
|
|
778
|
+
eventUtils.setGroup(false);
|
|
702
779
|
}
|
|
703
|
-
this.setStartBlock(block);
|
|
704
|
-
this.mostRecentEvent_ = e;
|
|
705
|
-
};
|
|
706
780
|
|
|
707
|
-
/**
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
781
|
+
/**
|
|
782
|
+
* Execute a workspace click. When in accessibility mode shift clicking will
|
|
783
|
+
* move the cursor.
|
|
784
|
+
* @param {!Event} _e A mouse up or touch end event.
|
|
785
|
+
* @private
|
|
786
|
+
*/
|
|
787
|
+
doWorkspaceClick_(_e) {
|
|
788
|
+
const ws = this.creatorWorkspace_;
|
|
789
|
+
if (common.getSelected()) {
|
|
790
|
+
common.getSelected().unselect();
|
|
791
|
+
}
|
|
792
|
+
this.fireWorkspaceClick_(this.startWorkspace_ || ws);
|
|
718
793
|
}
|
|
719
|
-
this.setStartBubble(bubble);
|
|
720
|
-
this.mostRecentEvent_ = e;
|
|
721
|
-
};
|
|
722
|
-
|
|
723
|
-
/* Begin functions defining what actions to take to execute clicks on each type
|
|
724
|
-
* of target. Any developer wanting to add behaviour on clicks should modify
|
|
725
|
-
* only this code. */
|
|
726
794
|
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
* @private
|
|
730
|
-
*/
|
|
731
|
-
Gesture.prototype.doBubbleClick_ = function() {
|
|
732
|
-
// TODO (#1673): Consistent handling of single clicks.
|
|
733
|
-
this.startBubble_.setFocus && this.startBubble_.setFocus();
|
|
734
|
-
this.startBubble_.select && this.startBubble_.select();
|
|
735
|
-
};
|
|
795
|
+
/* End functions defining what actions to take to execute clicks on each type
|
|
796
|
+
* of target. */
|
|
736
797
|
|
|
737
|
-
|
|
738
|
-
* Execute a field click.
|
|
739
|
-
* @private
|
|
740
|
-
*/
|
|
741
|
-
Gesture.prototype.doFieldClick_ = function() {
|
|
742
|
-
this.startField_.showEditor(this.mostRecentEvent_);
|
|
743
|
-
this.bringBlockToFront_();
|
|
744
|
-
};
|
|
798
|
+
// TODO (fenichel): Move bubbles to the front.
|
|
745
799
|
|
|
746
|
-
/**
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
if (this.targetBlock_.
|
|
754
|
-
|
|
755
|
-
eventUtils.setGroup(true);
|
|
756
|
-
}
|
|
757
|
-
const newBlock = this.flyout_.createBlock(this.targetBlock_);
|
|
758
|
-
newBlock.scheduleSnapAndBump();
|
|
800
|
+
/**
|
|
801
|
+
* Move the dragged/clicked block to the front of the workspace so that it is
|
|
802
|
+
* not occluded by other blocks.
|
|
803
|
+
* @private
|
|
804
|
+
*/
|
|
805
|
+
bringBlockToFront_() {
|
|
806
|
+
// Blocks in the flyout don't overlap, so skip the work.
|
|
807
|
+
if (this.targetBlock_ && !this.flyout_) {
|
|
808
|
+
this.targetBlock_.bringToFront();
|
|
759
809
|
}
|
|
760
|
-
} else {
|
|
761
|
-
// Clicks events are on the start block, even if it was a shadow.
|
|
762
|
-
const event = new (eventUtils.get(eventUtils.CLICK))(
|
|
763
|
-
this.startBlock_, this.startWorkspace_.id, 'block');
|
|
764
|
-
eventUtils.fire(event);
|
|
765
810
|
}
|
|
766
|
-
this.bringBlockToFront_();
|
|
767
|
-
eventUtils.setGroup(false);
|
|
768
|
-
};
|
|
769
811
|
|
|
770
|
-
|
|
771
|
-
* Execute a workspace click. When in accessibility mode shift clicking will
|
|
772
|
-
* move the cursor.
|
|
773
|
-
* @param {!Event} _e A mouse up or touch end event.
|
|
774
|
-
* @private
|
|
775
|
-
*/
|
|
776
|
-
Gesture.prototype.doWorkspaceClick_ = function(_e) {
|
|
777
|
-
const ws = this.creatorWorkspace_;
|
|
778
|
-
if (common.getSelected()) {
|
|
779
|
-
common.getSelected().unselect();
|
|
780
|
-
}
|
|
781
|
-
this.fireWorkspaceClick_(this.startWorkspace_ || ws);
|
|
782
|
-
};
|
|
812
|
+
/* Begin functions for populating a gesture at mouse down. */
|
|
783
813
|
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
814
|
+
/**
|
|
815
|
+
* Record the field that a gesture started on.
|
|
816
|
+
* @param {Field} field The field the gesture started on.
|
|
817
|
+
* @package
|
|
818
|
+
*/
|
|
819
|
+
setStartField(field) {
|
|
820
|
+
if (this.hasStarted_) {
|
|
821
|
+
throw Error(
|
|
822
|
+
'Tried to call gesture.setStartField, ' +
|
|
823
|
+
'but the gesture had already been started.');
|
|
824
|
+
}
|
|
825
|
+
if (!this.startField_) {
|
|
826
|
+
this.startField_ = field;
|
|
827
|
+
}
|
|
797
828
|
}
|
|
798
|
-
};
|
|
799
829
|
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
throw Error(
|
|
810
|
-
'Tried to call gesture.setStartField, ' +
|
|
811
|
-
'but the gesture had already been started.');
|
|
812
|
-
}
|
|
813
|
-
if (!this.startField_) {
|
|
814
|
-
this.startField_ = field;
|
|
830
|
+
/**
|
|
831
|
+
* Record the bubble that a gesture started on
|
|
832
|
+
* @param {IBubble} bubble The bubble the gesture started on.
|
|
833
|
+
* @package
|
|
834
|
+
*/
|
|
835
|
+
setStartBubble(bubble) {
|
|
836
|
+
if (!this.startBubble_) {
|
|
837
|
+
this.startBubble_ = bubble;
|
|
838
|
+
}
|
|
815
839
|
}
|
|
816
|
-
};
|
|
817
840
|
|
|
818
|
-
/**
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
841
|
+
/**
|
|
842
|
+
* Record the block that a gesture started on, and set the target block
|
|
843
|
+
* appropriately.
|
|
844
|
+
* @param {BlockSvg} block The block the gesture started on.
|
|
845
|
+
* @package
|
|
846
|
+
*/
|
|
847
|
+
setStartBlock(block) {
|
|
848
|
+
// If the gesture already went through a bubble, don't set the start block.
|
|
849
|
+
if (!this.startBlock_ && !this.startBubble_) {
|
|
850
|
+
this.startBlock_ = block;
|
|
851
|
+
if (block.isInFlyout && block !== block.getRootBlock()) {
|
|
852
|
+
this.setTargetBlock_(block.getRootBlock());
|
|
853
|
+
} else {
|
|
854
|
+
this.setTargetBlock_(block);
|
|
855
|
+
}
|
|
856
|
+
}
|
|
826
857
|
}
|
|
827
|
-
};
|
|
828
858
|
|
|
829
|
-
/**
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
if (block.isInFlyout && block !== block.getRootBlock()) {
|
|
840
|
-
this.setTargetBlock_(block.getRootBlock());
|
|
859
|
+
/**
|
|
860
|
+
* Record the block that a gesture targets, meaning the block that will be
|
|
861
|
+
* dragged if this turns into a drag. If this block is a shadow, that will be
|
|
862
|
+
* its first non-shadow parent.
|
|
863
|
+
* @param {BlockSvg} block The block the gesture targets.
|
|
864
|
+
* @private
|
|
865
|
+
*/
|
|
866
|
+
setTargetBlock_(block) {
|
|
867
|
+
if (block.isShadow()) {
|
|
868
|
+
this.setTargetBlock_(block.getParent());
|
|
841
869
|
} else {
|
|
842
|
-
this.
|
|
870
|
+
this.targetBlock_ = block;
|
|
843
871
|
}
|
|
844
872
|
}
|
|
845
|
-
};
|
|
846
|
-
|
|
847
|
-
/**
|
|
848
|
-
* Record the block that a gesture targets, meaning the block that will be
|
|
849
|
-
* dragged if this turns into a drag. If this block is a shadow, that will be
|
|
850
|
-
* its first non-shadow parent.
|
|
851
|
-
* @param {BlockSvg} block The block the gesture targets.
|
|
852
|
-
* @private
|
|
853
|
-
*/
|
|
854
|
-
Gesture.prototype.setTargetBlock_ = function(block) {
|
|
855
|
-
if (block.isShadow()) {
|
|
856
|
-
this.setTargetBlock_(block.getParent());
|
|
857
|
-
} else {
|
|
858
|
-
this.targetBlock_ = block;
|
|
859
|
-
}
|
|
860
|
-
};
|
|
861
873
|
|
|
862
|
-
/**
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
874
|
+
/**
|
|
875
|
+
* Record the workspace that a gesture started on.
|
|
876
|
+
* @param {WorkspaceSvg} ws The workspace the gesture started on.
|
|
877
|
+
* @private
|
|
878
|
+
*/
|
|
879
|
+
setStartWorkspace_(ws) {
|
|
880
|
+
if (!this.startWorkspace_) {
|
|
881
|
+
this.startWorkspace_ = ws;
|
|
882
|
+
}
|
|
870
883
|
}
|
|
871
|
-
};
|
|
872
884
|
|
|
873
|
-
/**
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
885
|
+
/**
|
|
886
|
+
* Record the flyout that a gesture started on.
|
|
887
|
+
* @param {IFlyout} flyout The flyout the gesture started on.
|
|
888
|
+
* @private
|
|
889
|
+
*/
|
|
890
|
+
setStartFlyout_(flyout) {
|
|
891
|
+
if (!this.flyout_) {
|
|
892
|
+
this.flyout_ = flyout;
|
|
893
|
+
}
|
|
881
894
|
}
|
|
882
|
-
};
|
|
883
895
|
|
|
896
|
+
/* End functions for populating a gesture at mouse down. */
|
|
884
897
|
|
|
885
|
-
/*
|
|
898
|
+
/* Begin helper functions defining types of clicks. Any developer wanting
|
|
899
|
+
* to change the definition of a click should modify only this code. */
|
|
886
900
|
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
const hasStartBubble = !!this.startBubble_;
|
|
899
|
-
return hasStartBubble && !this.hasExceededDragRadius_;
|
|
900
|
-
};
|
|
901
|
+
/**
|
|
902
|
+
* Whether this gesture is a click on a bubble. This should only be called
|
|
903
|
+
* when ending a gesture (mouse up, touch end).
|
|
904
|
+
* @return {boolean} Whether this gesture was a click on a bubble.
|
|
905
|
+
* @private
|
|
906
|
+
*/
|
|
907
|
+
isBubbleClick_() {
|
|
908
|
+
// A bubble click starts on a bubble and never escapes the drag radius.
|
|
909
|
+
const hasStartBubble = !!this.startBubble_;
|
|
910
|
+
return hasStartBubble && !this.hasExceededDragRadius_;
|
|
911
|
+
}
|
|
901
912
|
|
|
902
|
-
/**
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
913
|
+
/**
|
|
914
|
+
* Whether this gesture is a click on a block. This should only be called
|
|
915
|
+
* when ending a gesture (mouse up, touch end).
|
|
916
|
+
* @return {boolean} Whether this gesture was a click on a block.
|
|
917
|
+
* @private
|
|
918
|
+
*/
|
|
919
|
+
isBlockClick_() {
|
|
920
|
+
// A block click starts on a block, never escapes the drag radius, and is
|
|
921
|
+
// not a field click.
|
|
922
|
+
const hasStartBlock = !!this.startBlock_;
|
|
923
|
+
return hasStartBlock && !this.hasExceededDragRadius_ &&
|
|
924
|
+
!this.isFieldClick_();
|
|
925
|
+
}
|
|
914
926
|
|
|
915
|
-
/**
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
}
|
|
927
|
+
/**
|
|
928
|
+
* Whether this gesture is a click on a field. This should only be called
|
|
929
|
+
* when ending a gesture (mouse up, touch end).
|
|
930
|
+
* @return {boolean} Whether this gesture was a click on a field.
|
|
931
|
+
* @private
|
|
932
|
+
*/
|
|
933
|
+
isFieldClick_() {
|
|
934
|
+
const fieldClickable =
|
|
935
|
+
this.startField_ ? this.startField_.isClickable() : false;
|
|
936
|
+
return fieldClickable && !this.hasExceededDragRadius_ &&
|
|
937
|
+
(!this.flyout_ || !this.flyout_.autoClose);
|
|
938
|
+
}
|
|
927
939
|
|
|
928
|
-
/**
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
}
|
|
940
|
+
/**
|
|
941
|
+
* Whether this gesture is a click on a workspace. This should only be called
|
|
942
|
+
* when ending a gesture (mouse up, touch end).
|
|
943
|
+
* @return {boolean} Whether this gesture was a click on a workspace.
|
|
944
|
+
* @private
|
|
945
|
+
*/
|
|
946
|
+
isWorkspaceClick_() {
|
|
947
|
+
const onlyTouchedWorkspace =
|
|
948
|
+
!this.startBlock_ && !this.startBubble_ && !this.startField_;
|
|
949
|
+
return onlyTouchedWorkspace && !this.hasExceededDragRadius_;
|
|
950
|
+
}
|
|
939
951
|
|
|
940
|
-
/* End helper functions defining types of clicks. */
|
|
952
|
+
/* End helper functions defining types of clicks. */
|
|
941
953
|
|
|
942
|
-
/**
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
}
|
|
954
|
+
/**
|
|
955
|
+
* Whether this gesture is a drag of either a workspace or block.
|
|
956
|
+
* This function is called externally to block actions that cannot be taken
|
|
957
|
+
* mid-drag (e.g. using the keyboard to delete the selected blocks).
|
|
958
|
+
* @return {boolean} True if this gesture is a drag of a workspace or block.
|
|
959
|
+
* @package
|
|
960
|
+
*/
|
|
961
|
+
isDragging() {
|
|
962
|
+
return this.isDraggingWorkspace_ || this.isDraggingBlock_ ||
|
|
963
|
+
this.isDraggingBubble_;
|
|
964
|
+
}
|
|
953
965
|
|
|
954
|
-
/**
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
}
|
|
966
|
+
/**
|
|
967
|
+
* Whether this gesture has already been started. In theory every mouse down
|
|
968
|
+
* has a corresponding mouse up, but in reality it is possible to lose a
|
|
969
|
+
* mouse up, leaving an in-process gesture hanging.
|
|
970
|
+
* @return {boolean} Whether this gesture was a click on a workspace.
|
|
971
|
+
* @package
|
|
972
|
+
*/
|
|
973
|
+
hasStarted() {
|
|
974
|
+
return this.hasStarted_;
|
|
975
|
+
}
|
|
964
976
|
|
|
965
|
-
/**
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
977
|
+
/**
|
|
978
|
+
* Get a list of the insertion markers that currently exist. Block drags have
|
|
979
|
+
* 0, 1, or 2 insertion markers.
|
|
980
|
+
* @return {!Array<!BlockSvg>} A possibly empty list of insertion
|
|
981
|
+
* marker blocks.
|
|
982
|
+
* @package
|
|
983
|
+
*/
|
|
984
|
+
getInsertionMarkers() {
|
|
985
|
+
if (this.blockDragger_) {
|
|
986
|
+
return this.blockDragger_.getInsertionMarkers();
|
|
987
|
+
}
|
|
988
|
+
return [];
|
|
975
989
|
}
|
|
976
|
-
return [];
|
|
977
|
-
};
|
|
978
990
|
|
|
979
|
-
/**
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
991
|
+
/**
|
|
992
|
+
* Gets the current dragger if an item is being dragged. Null if nothing is
|
|
993
|
+
* being dragged.
|
|
994
|
+
* @return {!WorkspaceDragger|!BubbleDragger|!IBlockDragger|null}
|
|
995
|
+
* The dragger that is currently in use or null if no drag is in progress.
|
|
996
|
+
*/
|
|
997
|
+
getCurrentDragger() {
|
|
998
|
+
if (this.isDraggingBlock_) {
|
|
999
|
+
return this.blockDragger_;
|
|
1000
|
+
} else if (this.isDraggingWorkspace_) {
|
|
1001
|
+
return this.workspaceDragger_;
|
|
1002
|
+
} else if (this.isDraggingBubble_) {
|
|
1003
|
+
return this.bubbleDragger_;
|
|
1004
|
+
}
|
|
1005
|
+
return null;
|
|
992
1006
|
}
|
|
993
|
-
return null;
|
|
994
|
-
};
|
|
995
1007
|
|
|
996
|
-
/**
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1008
|
+
/**
|
|
1009
|
+
* Is a drag or other gesture currently in progress on any workspace?
|
|
1010
|
+
* @return {boolean} True if gesture is occurring.
|
|
1011
|
+
*/
|
|
1012
|
+
static inProgress() {
|
|
1013
|
+
const workspaces = Workspace.getAll();
|
|
1014
|
+
for (let i = 0, workspace; (workspace = workspaces[i]); i++) {
|
|
1015
|
+
// Not actually necessarily a WorkspaceSvg, but it doesn't matter b/c
|
|
1016
|
+
// we're just checking if the property exists. Theoretically we would
|
|
1017
|
+
// want to use instanceof, but that causes a circular dependency.
|
|
1018
|
+
if (/** @type {!WorkspaceSvg} */ (workspace).currentGesture_) {
|
|
1019
|
+
return true;
|
|
1020
|
+
}
|
|
1005
1021
|
}
|
|
1022
|
+
return false;
|
|
1006
1023
|
}
|
|
1007
|
-
|
|
1008
|
-
};
|
|
1024
|
+
}
|
|
1009
1025
|
|
|
1010
1026
|
exports.Gesture = Gesture;
|