Skip to content

Commit

Permalink
Merge pull request #171 from rachel-fenichel/cleanup/insertion_marker
Browse files Browse the repository at this point in the history
Rename ghosts to insertion markers and only store on global insertion marker
  • Loading branch information
rachel-fenichel committed Apr 7, 2016
2 parents efdc6a9 + 3a07be9 commit 1c8d86a
Show file tree
Hide file tree
Showing 8 changed files with 122 additions and 116 deletions.
30 changes: 12 additions & 18 deletions core/block.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,8 @@ Blockly.Block = function(workspace, prototypeName, opt_id) {
/** @type {boolean} */
this.RTL = workspace.RTL;

/** @type {Blockly.Block} */
this.ghostBlock_ = null;
/** @type {boolean} */
this.isGhost_ = false;
this.isInsertionMarker_ = false;

// Copy the type-specific functions and data from the prototype.
if (prototypeName) {
Expand Down Expand Up @@ -208,10 +206,6 @@ Blockly.Block.prototype.dispose = function(healStack) {
Blockly.selected = null;
}

if (this.ghostBlock_) {
this.ghostBlock_.dispose();
}

// First, dispose of all my children.
for (var i = this.childBlocks_.length - 1; i >= 0; i--) {
this.childBlocks_[i].dispose(false);
Expand Down Expand Up @@ -553,23 +547,23 @@ Blockly.Block.prototype.setShadow = function(shadow) {
};

/**
* Get whether this block is a ghost block or not.
* @return {boolean} True if a ghost.
* Get whether this block is an insertion marker block or not.
* @return {boolean} True if an insertion marker.
*/
Blockly.Block.prototype.isGhost = function() {
return this.isGhost_;
Blockly.Block.prototype.isInsertionMarker = function() {
return this.isInsertionMarker_;
};

/**
* Set whether this block is a ghost block or not.
* @param {boolean} ghost True if a ghost.
* Set whether this block is an insertion marker block or not.
* @param {boolean} insertionMarker True if an insertion marker.
*/
Blockly.Block.prototype.setGhost = function(ghost) {
if (this.isGhost_ == ghost) {
Blockly.Block.prototype.setInsertionMarker = function(insertionMarker) {
if (this.isInsertionMarker_ == insertionMarker) {
return; // No change.
}
this.isGhost_ = ghost;
if (this.isGhost_) {
this.isInsertionMarker_ = insertionMarker;
if (this.isInsertionMarker_) {
this.setColour("#949494");
}
};
Expand Down Expand Up @@ -632,7 +626,7 @@ Blockly.Block.prototype.setConnectionsHidden = function(hidden) {
/**
* Find the connection on this block that corresponds to the given connection
* on the other block.
* Used to match connections between a block and its ghost.
* Used to match connections between a block and its insertion marker.
* @param {!Blockly.Block} otherBlock The other block to match against.
* @param {!Blockly.Connection} conn The other connection to match.
* @return {Blockly.Connection} the matching connection on this block, or null.
Expand Down
2 changes: 1 addition & 1 deletion core/block_render_svg_horizontal.js
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ Blockly.BlockSvg.prototype.renderDraw_ = function(metrics) {
iconX = -metrics.width + Blockly.BlockSvg.SEP_SPACE_X / 1.5;
}
}
if (this.isGhost()) {
if (this.isInsertionMarker()) {
icon.setAttribute('display', 'none');
}
icon.setAttribute('transform',
Expand Down
113 changes: 58 additions & 55 deletions core/block_svg.js
Original file line number Diff line number Diff line change
Expand Up @@ -237,13 +237,13 @@ Blockly.BlockSvg.terminateDrag_ = function() {
if (Blockly.dragMode_ == Blockly.DRAG_FREE) {
// Terminate a drag operation.
if (selected) {
if (selected.ghostBlock_) {
if (Blockly.insertionMarker_) {
Blockly.Events.disable();
if (Blockly.localGhostConnection_) {
selected.disconnectGhost();
if (Blockly.insertionMarkerConnection_) {
Blockly.BlockSvg.disconnectInsertionMarker();
}
selected.ghostBlock_.dispose();
selected.ghostBlock_ = null;
Blockly.insertionMarker_.dispose();
Blockly.insertionMarker_ = null;
Blockly.Events.enable();
}
// Update the connection locations.
Expand Down Expand Up @@ -876,66 +876,67 @@ Blockly.BlockSvg.prototype.onMouseMove_ = function(e) {
*/
Blockly.BlockSvg.prototype.updatePreviews = function(closestConnection,
localConnection, radiusConnection, e, dx, dy) {
// Don't fire events for ghost block creation or movement.
// Don't fire events for insertion marker creation or movement.
Blockly.Events.disable();
// Remove a ghost if needed. For Scratch-Blockly we are using ghosts instead
// of highlighting the connection; for compatibility with Web Blockly the
// name "highlightedConnection" will still be used.
// Remove an insertion marker if needed. For Scratch-Blockly we are using
// grayed-out blocks instead of highlighting the connection; for compatibility
// with Web Blockly the name "highlightedConnection" will still be used.
if (Blockly.highlightedConnection_ &&
Blockly.highlightedConnection_ != closestConnection) {
if (this.ghostBlock_ && Blockly.localGhostConnection_) {
this.disconnectGhost();
if (Blockly.insertionMarker_ && Blockly.insertionMarkerConnection_) {
Blockly.BlockSvg.disconnectInsertionMarker();
}
Blockly.highlightedConnection_ = null;
Blockly.localConnection_ = null;
}

// Add a ghost if needed.
// Add an insertion marker if needed.
if (closestConnection &&
closestConnection != Blockly.highlightedConnection_ &&
!closestConnection.sourceBlock_.isGhost()) {
!closestConnection.sourceBlock_.isInsertionMarker()) {
Blockly.highlightedConnection_ = closestConnection;
Blockly.localConnection_ = localConnection;
if (!this.ghostBlock_){
this.ghostBlock_ = this.workspace.newBlock(this.type);
this.ghostBlock_.setGhost(true);
this.ghostBlock_.initSvg();
if (!Blockly.insertionMarker_){
Blockly.insertionMarker_ = this.workspace.newBlock(this.type);
Blockly.insertionMarker_.setInsertionMarker(true);
Blockly.insertionMarker_.initSvg();
}

var ghostBlock = this.ghostBlock_;
var localGhostConnection = ghostBlock.getMatchingConnection(this,
var insertionMarker = Blockly.insertionMarker_;
var insertionMarkerConnection = insertionMarker.getMatchingConnection(this,
localConnection);
if (localGhostConnection != Blockly.localGhostConnection_) {
ghostBlock.getSvgRoot().setAttribute('visibility', 'visible');
ghostBlock.rendered = true;
if (insertionMarkerConnection != Blockly.insertionMarkerConnection_) {
insertionMarker.getSvgRoot().setAttribute('visibility', 'visible');
insertionMarker.rendered = true;
// Move the preview to the correct location before the existing block.
if (localGhostConnection.type == Blockly.NEXT_STATEMENT) {
if (insertionMarkerConnection.type == Blockly.NEXT_STATEMENT) {
var relativeXy = this.getRelativeToSurfaceXY();
var connectionOffsetX = (localConnection.x_ - (relativeXy.x - dx));
var connectionOffsetY = (localConnection.y_ - (relativeXy.y - dy));
var newX = closestConnection.x_ - connectionOffsetX;
var newY = closestConnection.y_ - connectionOffsetY;
var ghostPosition = ghostBlock.getRelativeToSurfaceXY();
var insertionPosition = insertionMarker.getRelativeToSurfaceXY();

// If it's the first statement connection of a c-block, this block is
// going to get taller as soon as render() is called below.
if (localGhostConnection != ghostBlock.nextConnection) {
if (insertionMarkerConnection != insertionMarker.nextConnection) {
newY -= closestConnection.sourceBlock_.getHeightWidth().height -
Blockly.BlockSvg.MIN_BLOCK_Y;
}

ghostBlock.moveBy(newX - ghostPosition.x, newY - ghostPosition.y);
insertionMarker.moveBy(newX - insertionPosition.x,
newY - insertionPosition.y);

}
if (localGhostConnection.type == Blockly.PREVIOUS_STATEMENT &&
!ghostBlock.nextConnection) {
if (insertionMarkerConnection.type == Blockly.PREVIOUS_STATEMENT &&
!insertionMarker.nextConnection) {
Blockly.bumpedConnection_ = closestConnection.targetConnection;
}
// Renders ghost.
localGhostConnection.connect(closestConnection);
// Renders insertin marker.
insertionMarkerConnection.connect(closestConnection);
// Render dragging block so it appears on top.
this.workspace.getCanvas().appendChild(this.getSvgRoot());
Blockly.localGhostConnection_ = localGhostConnection;
Blockly.insertionMarkerConnection_ = insertionMarkerConnection;
}
}
// Reenable events.
Expand All @@ -949,40 +950,42 @@ Blockly.BlockSvg.prototype.updatePreviews = function(closestConnection,
};

/**
* Disconnect the current ghost block from the stack, and heal the stack to its
* previous state.
* Disconnect the current insertion marker from the stack, and heal the stack to
* its previous state.
*/
Blockly.BlockSvg.prototype.disconnectGhost = function() {
// The ghost block is the first block in a stack, either because it doesn't
// have a previous connection or because the previous connection is not
// connection. Unplug won't do anything in that case. Instead, unplug the
Blockly.BlockSvg.disconnectInsertionMarker = function() {
// The insertion marker is the first block in a stack, either because it
// doesn't have a previous connection or because the previous connection is
// not connected. Unplug won't do anything in that case. Instead, unplug the
// following block.
if (Blockly.localGhostConnection_ == this.ghostBlock_.nextConnection &&
(!this.ghostBlock_.previousConnection ||
!this.ghostBlock_.previousConnection.targetConnection)) {
Blockly.localGhostConnection_.targetBlock().unplug(false);
if (Blockly.insertionMarkerConnection_ ==
Blockly.insertionMarker_.nextConnection &&
(!Blockly.insertionMarker_.previousConnection ||
!Blockly.insertionMarker_.previousConnection.targetConnection)) {
Blockly.insertionMarkerConnection_.targetBlock().unplug(false);
}
// Inside of a C-block, first statement connection.
else if (Blockly.localGhostConnection_.type == Blockly.NEXT_STATEMENT &&
Blockly.localGhostConnection_ != this.ghostBlock_.nextConnection) {
var innerConnection = Blockly.localGhostConnection_.targetConnection;
else if (Blockly.insertionMarkerConnection_.type == Blockly.NEXT_STATEMENT &&
Blockly.insertionMarkerConnection_ !=
Blockly.insertionMarker_.nextConnection) {
var innerConnection = Blockly.insertionMarkerConnection_.targetConnection;
innerConnection.sourceBlock_.unplug(false);
var previousBlockNextConnection =
this.ghostBlock_.previousConnection.targetConnection;
this.ghostBlock_.unplug(true);
Blockly.insertionMarker_.previousConnection.targetConnection;
Blockly.insertionMarker_.unplug(true);
if (previousBlockNextConnection) {
previousBlockNextConnection.connect(innerConnection);
}
}
else {
this.ghostBlock_.unplug(true /* healStack */);
Blockly.insertionMarker_.unplug(true /* healStack */);
}

if (Blockly.localGhostConnection_.targetConnection) {
throw 'LocalGhostConnection still connected at the end of disconnectGhost';
if (Blockly.insertionMarkerConnection_.targetConnection) {
throw 'insertionMarkerConnection still connected at the end of disconnectInsertionMarker';
}
Blockly.localGhostConnection_ = null;
this.ghostBlock_.getSvgRoot().setAttribute('visibility', 'hidden');
Blockly.insertionMarkerConnection_ = null;
Blockly.insertionMarker_.getSvgRoot().setAttribute('visibility', 'hidden');
};

/**
Expand Down Expand Up @@ -1030,11 +1033,11 @@ Blockly.BlockSvg.prototype.setShadow = function(shadow) {
};

/**
* Set whether this block is a ghost block or not.
* @param {boolean} ghost True if a ghost.
* Set whether this block is an insertion marker block or not.
* @param {boolean} insertionMarker True if an insertion marker.
*/
Blockly.BlockSvg.prototype.setGhost = function(ghost) {
Blockly.BlockSvg.superClass_.setGhost.call(this, ghost);
Blockly.BlockSvg.prototype.setInsertionMarker = function(insertionMarker) {
Blockly.BlockSvg.superClass_.setInsertionMarker.call(this, insertionMarker);
this.updateColour();
};

Expand Down
18 changes: 13 additions & 5 deletions core/blockly.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,16 +83,24 @@ Blockly.highlightedConnection_ = null;
Blockly.localConnection_ = null;

/**
* Connection on ghost block that matches Blockly.localConnecxtion_ on the
* dragged block.
* Connection on the insertion marker block that matches
* Blockly.localConnection_ on the dragged block.
* @type {Blockly.Connection}
* @private
*/
Blockly.localGhostConnection_ = null;
Blockly.insertionMarkerConnection_ = null;

/**
* Connection that was bumped out of the way by a ghost block, and may need
* to be put back as the drag continues.
* Grayed-out block that indicates to the user what will happen if they release
* a drag immediately.
* @type {Blockly.Block}
* @private
*/
Blockly.insertionMarker_ = null;

/**
* Connection that was bumped out of the way by an insertion marker, and may
* need to be put back as the drag continues.
* @type {Blockly.Connection}
* @private
*/
Expand Down
23 changes: 12 additions & 11 deletions core/connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -296,11 +296,11 @@ Blockly.Connection.prototype.dispose = function() {
};

/**
* @return true if the connection is not connected or is connected to a ghost
* block, false otherwise.
* @return {boolean} true if the connection is not connected or is connected to
* an insertion marker, false otherwise.
*/
Blockly.Connection.prototype.isConnectedToNonGhost = function() {
return this.targetConnection && !this.targetBlock().isGhost();
Blockly.Connection.prototype.isConnectedToNonInsertionMarker = function() {
return this.targetConnection && !this.targetBlock().isInsertionMarker();
};

/**
Expand Down Expand Up @@ -416,10 +416,11 @@ Blockly.Connection.prototype.isConnectionAllowed = function(candidate,
return false;
}
if (candidate.targetConnection) {
// If the other side of this connection is the active ghost
// If the other side of this connection is the active insertion marker
// connection, we've obviously already decided that this is a good
// connection.
if (candidate.targetConnection == Blockly.localGhostConnection_) {
if (candidate.targetConnection ==
Blockly.insertionMarkerConnection_) {
return true;
} else {
return false;
Expand All @@ -441,7 +442,7 @@ Blockly.Connection.prototype.isConnectionAllowed = function(candidate,
// Can't connect this block's next connection unless we're connecting
// in front of the first block on a stack.
else if (this == this.sourceBlock_.nextConnection &&
candidate.isConnectedToNonGhost()) {
candidate.isConnectedToNonInsertionMarker()) {
return false;
}
}
Expand Down Expand Up @@ -473,13 +474,13 @@ Blockly.Connection.prototype.isConnectionAllowed = function(candidate,
// block on a stack or there's already a block connected inside the c.
if (firstStatementConnection &&
this == this.sourceBlock_.previousConnection &&
candidate.isConnectedToNonGhost() &&
candidate.isConnectedToNonInsertionMarker() &&
!firstStatementConnection.targetConnection) {
return false;
}
// Don't let a block with no next connection bump other blocks out of the
// stack.
if (candidate.isConnectedToNonGhost() &&
if (candidate.isConnectedToNonInsertionMarker() &&
!this.sourceBlock_.nextConnection) {
return false;
}
Expand All @@ -505,8 +506,8 @@ Blockly.Connection.prototype.checkBasicCompatibility_ = function(candidate,
return false;
}

// Don't consider ghost blocks.
if (candidate.sourceBlock_.isGhost()) {
// Don't consider insertion markers.
if (candidate.sourceBlock_.isInsertionMarker()) {
return false;
}

Expand Down
Loading

0 comments on commit 1c8d86a

Please # to comment.