From 144b7f4261670568382b7b38b07d861c16f07310 Mon Sep 17 00:00:00 2001 From: Rachel Fenichel Date: Thu, 5 Jan 2017 16:06:15 -0800 Subject: [PATCH] Don't connect to blocks under the flyout. --- core/block_svg.js | 57 ++++++++++++++++++++++++++++++++++++------- core/constants.js | 14 +++++++++++ core/workspace_svg.js | 22 ++++++----------- 3 files changed, 69 insertions(+), 24 deletions(-) diff --git a/core/block_svg.js b/core/block_svg.js index 8b2fd6aa8..056cb8052 100644 --- a/core/block_svg.js +++ b/core/block_svg.js @@ -690,7 +690,12 @@ Blockly.BlockSvg.prototype.onMouseUp_ = function(e) { new Blockly.Events.Ui(this, 'click', undefined, undefined)); } Blockly.terminateDrag_(); - if (Blockly.selected && Blockly.highlightedConnection_) { + + var deleteArea = this.workspace.isDeleteArea(e); + + // Connect to a nearby block, but not if it's over the toolbox. + if (Blockly.selected && Blockly.highlightedConnection_ && + deleteArea != Blockly.DELETE_AREA_TOOLBOX) { // Connect two blocks together. Blockly.localConnection_.connect(Blockly.highlightedConnection_); if (this.rendered) { @@ -704,8 +709,9 @@ Blockly.BlockSvg.prototype.onMouseUp_ = function(e) { // Don't throw an object in the trash can if it just got connected. this.workspace.trashcan.close(); } - } else if (!this.getParent() && Blockly.selected.isDeletable() && - this.workspace.isDeleteArea(e)) { + } else if (deleteArea && !this.getParent() && Blockly.selected.isDeletable()) { + // We didn't connect the block, and it was over the trash can or the + // toolbox. Delete it. var trashcan = this.workspace.trashcan; Blockly.confirmDeletion(function(confirmedDelete) { if (trashcan) { @@ -1024,24 +1030,57 @@ Blockly.BlockSvg.prototype.onMouseMove_ = function(e) { Blockly.highlightedConnection_ = null; Blockly.localConnection_ = null; } + + var wouldDeleteBlock = this.updateCursor_(e, closestConnection); + // Add connection highlighting if needed. - if (closestConnection && + if (!wouldDeleteBlock && closestConnection && closestConnection != Blockly.highlightedConnection_) { closestConnection.highlight(); Blockly.highlightedConnection_ = closestConnection; Blockly.localConnection_ = localConnection; } - // Provide visual indication of whether the block will be deleted if - // dropped here. - if (this.isDeletable()) { - this.workspace.isDeleteArea(e); - } } // This event has been handled. No need to bubble up to the document. e.stopPropagation(); e.preventDefault(); }; +/** + * Provide visual indication of whether the block will be deleted if + * dropped here. + * Prefer connecting over dropping into the trash can, but prefer dragging to + * the toolbox over connecting to other blocks. + * @param {!Event} e Mouse move event. + * @param {Blockly.Connection} closestConnection The connection this block would + * potentially connect to if dropped here, or null. + * @return {boolean} True if the block would be deleted if dropped here, + * otherwise false. + * @private + */ +Blockly.BlockSvg.prototype.updateCursor_ = function(e, closestConnection) { + var deleteArea = this.workspace.isDeleteArea(e); + var wouldConnect = Blockly.selected && closestConnection && + deleteArea != Blockly.DELETE_AREA_TOOLBOX; + var wouldDelete = deleteArea && !this.getParent() && + Blockly.selected.isDeletable(); + var showDeleteCursor = wouldDelete && !wouldConnect; + + if (showDeleteCursor) { + Blockly.Css.setCursor(Blockly.Css.Cursor.DELETE); + if (deleteArea == Blockly.DELETE_AREA_TRASH && this.workspace.trashcan) { + this.workspace.trashcan.setOpen_(true); + } + return true; + } else { + Blockly.Css.setCursor(Blockly.Css.Cursor.CLOSED); + if (this.workspace.trashcan) { + this.workspace.trashcan.setOpen_(false); + } + return false; + } +}; + /** * Add or remove the UI indicating if this block is movable or not. */ diff --git a/core/constants.js b/core/constants.js index 0f327e2d9..5805229bf 100644 --- a/core/constants.js +++ b/core/constants.js @@ -200,3 +200,17 @@ Blockly.TOOLBOX_AT_LEFT = 2; * @const */ Blockly.TOOLBOX_AT_RIGHT = 3; + + +/** + * ENUM representing that an event is in the delete area of the trash can. + * @const + */ +Blockly.DELETE_AREA_TRASH = 1; + +/** + * ENUM representing that an event is in the delete area of the toolbox or + * flyout. + * @const + */ +Blockly.DELETE_AREA_TOOLBOX = 2; diff --git a/core/workspace_svg.js b/core/workspace_svg.js index 67522f0e7..d1d850a7c 100644 --- a/core/workspace_svg.js +++ b/core/workspace_svg.js @@ -875,26 +875,18 @@ Blockly.WorkspaceSvg.prototype.recordDeleteAreas = function() { * Is the mouse event over a delete area (toolbox or non-closing flyout)? * Opens or closes the trashcan and sets the cursor as a side effect. * @param {!Event} e Mouse move event. - * @return {boolean} True if event is in a delete area. + * @return {?number} Null if not over a delete area, or an enum representing + * which delete area the event is over. */ Blockly.WorkspaceSvg.prototype.isDeleteArea = function(e) { var xy = new goog.math.Coordinate(e.clientX, e.clientY); - if (this.deleteAreaTrash_) { - if (this.deleteAreaTrash_.contains(xy)) { - this.trashcan.setOpen_(true); - Blockly.Css.setCursor(Blockly.Css.Cursor.DELETE); - return true; - } - this.trashcan.setOpen_(false); + if (this.deleteAreaTrash_ && this.deleteAreaTrash_.contains(xy)) { + return Blockly.DELETE_AREA_TRASH; } - if (this.deleteAreaToolbox_) { - if (this.deleteAreaToolbox_.contains(xy)) { - Blockly.Css.setCursor(Blockly.Css.Cursor.DELETE); - return true; - } + if (this.deleteAreaToolbox_ && this.deleteAreaToolbox_.contains(xy)) { + return Blockly.DELETE_AREA_TOOLBOX; } - Blockly.Css.setCursor(Blockly.Css.Cursor.CLOSED); - return false; + return null; }; /**