Add onDragOver and wouldDelete_ to DeleteArea (#4888)

* keep track of state for whether the block or bubble would be deleted for use with drag enter exit

* Check if block and bubble is deletable in IDeleteArea

* Add to jsdoc of IDeleteArea
This commit is contained in:
Monica Kozbial
2021-06-10 16:27:04 -07:00
committed by GitHub
parent 2c15a0dfb1
commit 2005576036
9 changed files with 76 additions and 35 deletions

View File

@@ -228,16 +228,11 @@ Blockly.BlockDragger.prototype.fireDragStartEvent_ = function() {
Blockly.BlockDragger.prototype.drag = function(e, currentDragDeltaXY) {
var delta = this.pixelsToWorkspaceUnits_(currentDragDeltaXY);
var newLoc = Blockly.utils.Coordinate.sum(this.startXY_, delta);
this.draggingBlock_.moveDuringDrag(newLoc);
this.dragIcons_(delta);
var oldDragTarget = this.dragTarget_;
this.dragTarget_ = this.workspace_.getDragTarget(e);
if (this.dragTarget_ !== oldDragTarget) {
oldDragTarget && oldDragTarget.onDragExit();
this.dragTarget_ && this.dragTarget_.onDragEnter();
}
this.draggedConnectionManager_.update(delta, this.dragTarget_);
var oldWouldDeleteBlock = this.wouldDeleteBlock_;
@@ -246,6 +241,14 @@ Blockly.BlockDragger.prototype.drag = function(e, currentDragDeltaXY) {
// Prevent unnecessary add/remove class calls.
this.updateCursorDuringBlockDrag_();
}
// Call drag enter/exit/over after wouldDeleteBlock is called in
// InsertionMarkerManager.update.
if (this.dragTarget_ !== oldDragTarget) {
oldDragTarget && oldDragTarget.onDragExit();
this.dragTarget_ && this.dragTarget_.onDragEnter();
}
this.dragTarget_ && this.dragTarget_.onDragOver();
};
/**

View File

@@ -132,15 +132,10 @@ Blockly.BubbleDragger.prototype.startBubbleDrag = function() {
Blockly.BubbleDragger.prototype.dragBubble = function(e, currentDragDeltaXY) {
var delta = this.pixelsToWorkspaceUnits_(currentDragDeltaXY);
var newLoc = Blockly.utils.Coordinate.sum(this.startXY_, delta);
this.draggingBubble_.moveDuringDrag(this.dragSurface_, newLoc);
var oldDragTarget = this.dragTarget_;
this.dragTarget_ = this.workspace_.getDragTarget(e);
if (this.dragTarget_ !== oldDragTarget) {
oldDragTarget && oldDragTarget.onDragExit();
this.dragTarget_ && this.dragTarget_.onDragEnter();
}
var oldWouldDeleteBubble = this.wouldDeleteBubble_;
this.wouldDeleteBubble_ = this.shouldDelete_(this.dragTarget_);
@@ -148,6 +143,12 @@ Blockly.BubbleDragger.prototype.dragBubble = function(e, currentDragDeltaXY) {
// Prevent unnecessary add/remove class calls.
this.updateCursorDuringBubbleDrag_();
}
if (this.dragTarget_ !== oldDragTarget) {
oldDragTarget && oldDragTarget.onDragExit();
this.dragTarget_ && this.dragTarget_.onDragEnter();
}
this.dragTarget_ && this.dragTarget_.onDragOver();
};
/**
@@ -159,9 +160,7 @@ Blockly.BubbleDragger.prototype.dragBubble = function(e, currentDragDeltaXY) {
* @private
*/
Blockly.BubbleDragger.prototype.shouldDelete_ = function(dragTarget) {
var couldDeleteBubble = this.draggingBubble_.isDeletable();
if (couldDeleteBubble && dragTarget) {
if (dragTarget) {
var componentManager = this.workspace_.getComponentManager();
var isDeleteArea = componentManager.hasCapability(dragTarget.id,
Blockly.ComponentManager.Capability.DELETE_AREA);

View File

@@ -27,27 +27,42 @@ goog.require('Blockly.IDeleteArea');
*/
Blockly.DeleteArea = function() {
Blockly.DeleteArea.superClass_.constructor.call(this);
/**
* Whether the current block or bubble dragged over this delete area would be
* deleted if dropped on this component.
* @type {boolean}
* @protected
*/
this.wouldDelete_ = false;
};
Blockly.utils.object.inherits(Blockly.DeleteArea, Blockly.DragTarget);
/**
* Returns whether the provided block would be deleted if dropped on this area.
* @param {!Blockly.BlockSvg} _block The block.
* This method should check if the block is deletable and is always called
* before onDragEnter/onDragOver/onDragExit.
* @param {!Blockly.BlockSvg} block The block.
* @param {boolean} couldConnect Whether the block could could connect to
* another.
* @return {boolean} Whether the block provided would be deleted if dropped on
* this area.
*/
Blockly.DeleteArea.prototype.wouldDeleteBlock = function(_block, couldConnect) {
return !couldConnect;
Blockly.DeleteArea.prototype.wouldDeleteBlock = function(block, couldConnect) {
var couldDeleteBlock = !block.getParent() && block.isDeletable();
this.wouldDelete_ = couldDeleteBlock && !couldConnect;
return this.wouldDelete_;
};
/**
* Returns whether the provided bubble would be deleted if dropped on this area.
* @param {!Blockly.IBubble} _bubble The bubble.
* This method should check if the bubble is deletable and is always called
* before onDragEnter/onDragOver/onDragExit.
* @param {!Blockly.IBubble} bubble The bubble.
* @return {boolean} Whether the bubble provided would be deleted if dropped on
* this area.
*/
Blockly.DeleteArea.prototype.wouldDeleteBubble = function(_bubble) {
return true;
Blockly.DeleteArea.prototype.wouldDeleteBubble = function(bubble) {
this.wouldDelete_ = bubble.isDeletable();
return this.wouldDelete_;
};

View File

@@ -44,6 +44,14 @@ Blockly.DragTarget.prototype.onDragEnter = function() {
// no-op
};
/**
* Handles when a cursor with a block or bubble is dragged over this drag
* target.
*/
Blockly.DragTarget.prototype.onDragOver = function() {
// no-op
};
/**
* Handles when a cursor with a block or bubble exits this drag target.
*/

View File

@@ -456,10 +456,7 @@ Blockly.InsertionMarkerManager.prototype.getStartRadius_ = function() {
*/
Blockly.InsertionMarkerManager.prototype.shouldDelete_ = function(
candidate, dragTarget) {
var couldDeleteBlock =
!this.topBlock_.getParent() && this.topBlock_.isDeletable();
if (couldDeleteBlock && dragTarget) {
if (dragTarget) {
var componentManager = this.workspace_.getComponentManager();
var isDeleteArea = componentManager.hasCapability(dragTarget.id,
Blockly.ComponentManager.Capability.DELETE_AREA);

View File

@@ -30,6 +30,8 @@ Blockly.IDeleteArea = function() {};
/**
* Returns whether the provided block would be deleted if dropped on this area.
* This method should check if the block is deletable and is always called
* before onDragEnter/onDragOver/onDragExit.
* @param {!Blockly.BlockSvg} block The block.
* @param {boolean} couldConnect Whether the block could could connect to
* another.
@@ -40,6 +42,8 @@ Blockly.IDeleteArea.prototype.wouldDeleteBlock;
/**
* Returns whether the provided bubble would be deleted if dropped on this area.
* This method should check if the bubble is deletable and is always called
* before onDragEnter/onDragOver/onDragExit.
* @param {!Blockly.IBubble} bubble The bubble.
* @return {boolean} Whether the bubble provided would be deleted if dropped on
* this area.

View File

@@ -40,6 +40,13 @@ Blockly.IDragTarget.prototype.getClientRect;
*/
Blockly.IDragTarget.prototype.onDragEnter;
/**
* Handles when a cursor with a block or bubble is dragged over this drag
* target.
*/
Blockly.IDragTarget.prototype.onDragOver;
/**
* Handles when a cursor with a block or bubble exits this drag target.
*/

View File

@@ -541,15 +541,19 @@ Blockly.Toolbox.prototype.getClientRect = function() {
/**
* Returns whether the provided block would be deleted if dropped on this area.
* @param {!Blockly.BlockSvg} _block The block.
* This method should check if the block is deletable and is always called
* before onDragEnter/onDragOver/onDragExit.
* @param {!Blockly.BlockSvg} block The block.
* @param {boolean} _couldConnect Whether the block could could connect to
* another.
* @return {boolean} Whether the block provided would be deleted if dropped on
* this area.
* @override
*/
Blockly.Toolbox.prototype.wouldDeleteBlock = function(_block, _couldConnect) {
Blockly.Toolbox.prototype.wouldDeleteBlock = function(block, _couldConnect) {
// Prefer dragging to the toolbox over connecting to other blocks.
return true;
this.wouldDelete_ = !block.getParent() && block.isDeletable();
return this.wouldDelete_;
};
/**

View File

@@ -533,11 +533,13 @@ Blockly.Trashcan.prototype.getClientRect = function() {
};
/**
* Handles when a cursor with a block or bubble enters this drag target.
* Handles when a cursor with a block or bubble is dragged over this drag
* target.
* @override
*/
Blockly.Trashcan.prototype.onDragEnter = function() {
this.setLidOpen(true);
Blockly.Trashcan.prototype.onDragOver = function() {
Blockly.Trashcan.superClass_.onDragOver.call(this);
this.setLidOpen(this.wouldDelete_);
};
/**
@@ -545,27 +547,29 @@ Blockly.Trashcan.prototype.onDragEnter = function() {
* @override
*/
Blockly.Trashcan.prototype.onDragExit = function() {
Blockly.Trashcan.superClass_.onDragExit.call(this);
this.setLidOpen(false);
};
/**
* Handles when a block is dropped on this component. Should not handle delete
* here.
* @param {!Blockly.BlockSvg} _block The block.
* @param {!Blockly.BlockSvg} block The block.
* @override
*/
Blockly.Trashcan.prototype.onBlockDrop = function(_block) {
Blockly.Trashcan.prototype.onBlockDrop = function(block) {
Blockly.Trashcan.superClass_.onBlockDrop.call(this, block);
this.onDrop_();
};
/**
* Handles when a bubble is dropped on this component. Should not handle delete
* here.
* @param {!Blockly.IBubble} _bubble The bubble.
* @param {!Blockly.IBubble} bubble The bubble.
* @override
*/
Blockly.Trashcan.prototype.onBubbleDrop = function(_bubble) {
Blockly.Trashcan.prototype.onBubbleDrop = function(bubble) {
Blockly.Trashcan.superClass_.onBubbleDrop.call(this, bubble);
this.onDrop_();
};
@@ -574,7 +578,7 @@ Blockly.Trashcan.prototype.onBubbleDrop = function(_bubble) {
* @private
*/
Blockly.Trashcan.prototype.onDrop_ = function() {
setTimeout(this.closeLid.bind(this), 100);
setTimeout(this.setLidOpen.bind(this, false), 100);
};
/**