Skip to content

Commit

Permalink
Adding IDragTarget support. (#4852)
Browse files Browse the repository at this point in the history
  • Loading branch information
moniika committed Jun 9, 2021
1 parent 861a981 commit 1139034
Show file tree
Hide file tree
Showing 18 changed files with 505 additions and 204 deletions.
13 changes: 8 additions & 5 deletions blockly_uncompressed.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

70 changes: 24 additions & 46 deletions core/block_dragger.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ goog.require('Blockly.utils.Coordinate');
goog.require('Blockly.utils.dom');

goog.requireType('Blockly.BlockSvg');
goog.requireType('Blockly.IDragTarget');
goog.requireType('Blockly.WorkspaceSvg');


Expand Down Expand Up @@ -59,13 +60,11 @@ Blockly.BlockDragger = function(block, workspace) {
this.draggingBlock_);

/**
* Which delete area the mouse pointer is over, if any.
* One of {@link Blockly.DELETE_AREA_TRASH},
* {@link Blockly.DELETE_AREA_TOOLBOX}, or {@link Blockly.DELETE_AREA_NONE}.
* @type {?number}
* Which drag area the mouse pointer is over, if any.
* @type {?Blockly.IDragTarget}
* @private
*/
this.deleteArea_ = null;
this.dragTarget_ = null;

/**
* Whether the block would be deleted if dropped immediately.
Expand Down Expand Up @@ -210,8 +209,15 @@ Blockly.BlockDragger.prototype.dragBlock = function(e, currentDragDeltaXY) {
this.draggingBlock_.moveDuringDrag(newLoc);
this.dragIcons_(delta);

this.deleteArea_ = this.workspace_.isDeleteArea(e);
this.draggedConnectionManager_.update(delta, this.deleteArea_);
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_);
this.wouldDeleteBlock_ = this.draggedConnectionManager_.wouldDeleteBlock();

this.updateCursorDuringBlockDrag_();
};
Expand All @@ -237,8 +243,16 @@ Blockly.BlockDragger.prototype.endBlockDrag = function(e, currentDragDeltaXY) {
var newLoc = Blockly.utils.Coordinate.sum(this.startXY_, delta);
this.draggingBlock_.moveOffDragSurface(newLoc);

var deleted = this.maybeDeleteBlock_();
if (!deleted) {
if (this.dragTarget_) {
this.dragTarget_.onBlockDrop(this.draggingBlock_);
}

if (this.wouldDeleteBlock_) {
// Fire a move event, so we know where to go back to for an undo.
this.fireMoveEvent_();
this.draggingBlock_.dispose(false, true);
Blockly.draggingConnections = [];
} else {
// These are expensive and don't need to be done if we're deleting.
this.draggingBlock_.moveConnections(delta.x, delta.y);
this.draggingBlock_.setDragging(false);
Expand Down Expand Up @@ -284,49 +298,13 @@ Blockly.BlockDragger.prototype.fireMoveEvent_ = function() {
Blockly.Events.fire(event);
};

/**
* Shut the trash can and, if necessary, delete the dragging block.
* Should be called at the end of a block drag.
* @return {boolean} Whether the block was deleted.
* @private
*/
Blockly.BlockDragger.prototype.maybeDeleteBlock_ = function() {
var trashcan = this.workspace_.trashcan;

if (this.wouldDeleteBlock_) {
if (trashcan) {
setTimeout(trashcan.closeLid.bind(trashcan), 100);
}
// Fire a move event, so we know where to go back to for an undo.
this.fireMoveEvent_();
this.draggingBlock_.dispose(false, true);
Blockly.draggingConnections = [];
} else if (trashcan) {
// Make sure the trash can lid is closed.
trashcan.closeLid();
}
return this.wouldDeleteBlock_;
};

/**
* Update the cursor (and possibly the trash can lid) to reflect whether the
* dragging block would be deleted if released immediately.
* @private
*/
Blockly.BlockDragger.prototype.updateCursorDuringBlockDrag_ = function() {
this.wouldDeleteBlock_ = this.draggedConnectionManager_.wouldDeleteBlock();
var trashcan = this.workspace_.trashcan;
if (this.wouldDeleteBlock_) {
this.draggingBlock_.setDeleteStyle(true);
if (this.deleteArea_ == Blockly.DELETE_AREA_TRASH && trashcan) {
trashcan.setLidOpen(true);
}
} else {
this.draggingBlock_.setDeleteStyle(false);
if (trashcan) {
trashcan.setLidOpen(false);
}
}
this.draggingBlock_.setDeleteStyle(this.wouldDeleteBlock_);
};

/**
Expand Down
72 changes: 38 additions & 34 deletions core/bubble_dragger.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,11 @@ Blockly.BubbleDragger = function(bubble, workspace) {
this.workspace_ = workspace;

/**
* Which delete area the mouse pointer is over, if any.
* One of {@link Blockly.DELETE_AREA_TRASH},
* {@link Blockly.DELETE_AREA_TOOLBOX}, or {@link Blockly.DELETE_AREA_NONE}.
* @type {?number}
* Which drag target the mouse pointer is over, if any.
* @type {?Blockly.IDragTarget}
* @private
*/
this.deleteArea_ = null;
this.dragTarget_ = null;

/**
* Whether the bubble would be deleted if dropped immediately.
Expand Down Expand Up @@ -136,33 +134,41 @@ Blockly.BubbleDragger.prototype.dragBubble = function(e, currentDragDeltaXY) {

this.draggingBubble_.moveDuringDrag(this.dragSurface_, newLoc);

if (this.draggingBubble_.isDeletable()) {
this.deleteArea_ = this.workspace_.isDeleteArea(e);
this.updateCursorDuringBubbleDrag_();
var oldDragTarget = this.dragTarget_;
this.dragTarget_ = this.workspace_.getDragTarget(e);
if (this.dragTarget_ !== oldDragTarget) {
oldDragTarget && oldDragTarget.onDragExit();
this.dragTarget_ && this.dragTarget_.onDragEnter();
}
this.wouldDeleteBubble_ = this.shouldDelete_(this.dragTarget_);

this.updateCursorDuringBubbleDrag_();
};

/**
* Shut the trash can and, if necessary, delete the dragging bubble.
* Should be called at the end of a bubble drag.
* @return {boolean} Whether the bubble was deleted.
* Whether ending the drag would delete the bubble.
* @param {?Blockly.IDragTarget} dragTarget The drag target that the bubblee is
* currently over.
* @return {boolean} Whether dropping the bubble immediately would delete the
* block.
* @private
*/
Blockly.BubbleDragger.prototype.maybeDeleteBubble_ = function() {
var trashcan = this.workspace_.trashcan;
Blockly.BubbleDragger.prototype.shouldDelete_ = function(dragTarget) {
var couldDeleteBubble = this.draggingBubble_.isDeletable();

if (this.wouldDeleteBubble_) {
if (trashcan) {
setTimeout(trashcan.closeLid.bind(trashcan), 100);
if (couldDeleteBubble && dragTarget) {
// TODO(#4881) use hasCapability instead of getComponents
var deleteAreas = this.workspace_.getComponentManager().getComponents(
Blockly.ComponentManager.Capability.DELETE_AREA, false);
var isDeleteArea = deleteAreas.some(function(deleteArea) {
return dragTarget === deleteArea;
});
if (isDeleteArea) {
return (/** @type {!Blockly.IDeleteArea} */ (dragTarget))
.wouldDeleteBubble(this.draggingBubble_);
}
// Fire a move event, so we know where to go back to for an undo.
this.fireMoveEvent_();
this.draggingBubble_.dispose(false, true);
} else if (trashcan) {
// Make sure the trash can lid is closed.
trashcan.closeLid();
}
return this.wouldDeleteBubble_;
return false;
};

/**
Expand All @@ -171,18 +177,10 @@ Blockly.BubbleDragger.prototype.maybeDeleteBubble_ = function() {
* @private
*/
Blockly.BubbleDragger.prototype.updateCursorDuringBubbleDrag_ = function() {
this.wouldDeleteBubble_ = this.deleteArea_ != Blockly.DELETE_AREA_NONE;
var trashcan = this.workspace_.trashcan;
if (this.wouldDeleteBubble_) {
this.draggingBubble_.setDeleteStyle(true);
if (this.deleteArea_ == Blockly.DELETE_AREA_TRASH && trashcan) {
trashcan.setLidOpen(true);
}
} else {
this.draggingBubble_.setDeleteStyle(false);
if (trashcan) {
trashcan.setLidOpen(false);
}
}
};

Expand All @@ -200,12 +198,18 @@ Blockly.BubbleDragger.prototype.endBubbleDrag = function(

var delta = this.pixelsToWorkspaceUnits_(currentDragDeltaXY);
var newLoc = Blockly.utils.Coordinate.sum(this.startXY_, delta);

// Move the bubble to its final location.
this.draggingBubble_.moveTo(newLoc.x, newLoc.y);
var deleted = this.maybeDeleteBubble_();

if (!deleted) {
if (this.dragTarget_) {
this.dragTarget_.onBubbleDrop(this.draggingBubble_);
}

if (this.wouldDeleteBubble_) {
// Fire a move event, so we know where to go back to for an undo.
this.fireMoveEvent_();
this.draggingBubble_.dispose(false, true);
} else {
// Put everything back onto the bubble canvas.
if (this.dragSurface_) {
this.dragSurface_.clearAndHide(this.workspace_.getBubbleCanvas());
Expand Down
11 changes: 11 additions & 0 deletions core/component_manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ goog.provide('Blockly.ComponentManager');

goog.requireType('Blockly.IAutoHideable');
goog.requireType('Blockly.IComponent');
goog.requireType('Blockly.IDeleteArea');
goog.requireType('Blockly.IDragTarget');
goog.requireType('Blockly.IPositionable');


Expand Down Expand Up @@ -206,6 +208,15 @@ Blockly.ComponentManager.Capability.prototype.toString = function() {
/** @type {!Blockly.ComponentManager.Capability<!Blockly.IPositionable>} */
Blockly.ComponentManager.Capability.POSITIONABLE =
new Blockly.ComponentManager.Capability('positionable');

/** @type {!Blockly.ComponentManager.Capability<!Blockly.IDragTarget>} */
Blockly.ComponentManager.Capability.DRAG_TARGET =
new Blockly.ComponentManager.Capability('drag_target');

/** @type {!Blockly.ComponentManager.Capability<!Blockly.IDeleteArea>} */
Blockly.ComponentManager.Capability.DELETE_AREA =
new Blockly.ComponentManager.Capability('delete_area');

/** @type {!Blockly.ComponentManager.Capability<!Blockly.IAutoHideable>} */
Blockly.ComponentManager.Capability.AUTOHIDEABLE =
new Blockly.ComponentManager.Capability('autohideable');
20 changes: 0 additions & 20 deletions core/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,26 +161,6 @@ Blockly.OPPOSITE_TYPE[Blockly.connectionTypes.NEXT_STATEMENT] =
Blockly.OPPOSITE_TYPE[Blockly.connectionTypes.PREVIOUS_STATEMENT] =
Blockly.connectionTypes.NEXT_STATEMENT;

/**
* ENUM representing that an event is not in any delete areas.
* Null for backwards compatibility reasons.
* @const
*/
Blockly.DELETE_AREA_NONE = null;

/**
* 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;

/**
* String for use in the "custom" attribute of a category in toolbox XML.
* This string indicates that the category should be dynamically populated with
Expand Down
Loading

0 comments on commit 1139034

Please sign in to comment.