cloud-blocks
Version:
Cloud Blocks is a library for building scratch computing interfaces with Luxrobo MODI.
223 lines (199 loc) • 7.17 kB
JavaScript
/**
* @license
* Visual Blocks Editor
*
* Copyright 2017 Google Inc.
* https://developers.google.com/blockly/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Methods for dragging a block visually.
* @author fenichel@google.com (Rachel Fenichel)
*/
'use strict';
goog.provide('Blockly.CengageBlockDragger');
goog.require('Blockly.BlockAnimations');
goog.require('Blockly.Events.BlockMove');
goog.require('Blockly.Events.DragBlockOutside');
goog.require('Blockly.Events.EndBlockDrag');
goog.require('Blockly.InsertionMarkerManager');
goog.require('goog.math.Coordinate');
goog.require('goog.asserts');
/**
* Class for a block dragger. It moves blocks around the workspace when they
* are being dragged by a mouse or touch.
* @author Sophie
* @param {!Blockly.BlockSvg} block The block to drag.
* @param {!Blockly.WorkspaceSvg} workspace The workspace to drag on.
* @extends Blockly.BlockDragger
* @constructor
*/
Blockly.CengageBlockDragger = function (block, workspace) {
Blockly.CengageBlockDragger.superClass_.constructor.call(
this,
block,
workspace
);
};
goog.inherits(Blockly.CengageBlockDragger, Blockly.BlockDragger);
// make tutorial visible or invisible
Blockly.CengageBlockDragger.prototype.setTutorial = function (visible) {
var tutorialElem = document.querySelector('.tutorial-wrapper');
if (visible) {
tutorialElem.style.display = 'block';
} else {
tutorialElem.style.display = 'none';
}
};
// check if dragging block has parent which is control forever.
Blockly.CengageBlockDragger.prototype.checkParentBlock = function () {
var parentBlock = this.draggingBlock_.getParent();
if (parentBlock && parentBlock.type === 'control_forever') {
// correct answer
this.workspace_.tutorialOn = false;
window.android.completeTutorialOfScratch();
} else {
// wrong answer
var ws = this.workspace_;
setTimeout(function () {
ws.undo(false);
});
this.setTutorial(true);
this.workspace_.tutorialOn = true;
}
};
Blockly.CengageBlockDragger.prototype.endTutorial = function () {
if (this.workspace_.tutorialOn) {
this.checkParentBlock();
}
};
/**
* Finish a block drag and put the block back on the workspace.
* @param {!Event} e The mouseup/touchend event.
* @param {!goog.math.Coordinate} currentDragDeltaXY How far the pointer has
* moved from the position at the start of the drag, in pixel units.
* @package
*/
Blockly.CengageBlockDragger.prototype.endBlockDrag = function (
e,
currentDragDeltaXY
) {
// Make sure internal state is fresh.
this.dragBlock(e, currentDragDeltaXY);
this.dragIconData_ = [];
var isOutside = this.wasOutside_;
this.fireEndDragEvent_(isOutside);
this.draggingBlock_.setMouseThroughStyle(false);
Blockly.BlockAnimations.disconnectUiStop();
var delta = this.pixelsToWorkspaceUnits_(currentDragDeltaXY);
var newLoc = goog.math.Coordinate.sum(this.startXY_, delta);
this.draggingBlock_.moveOffDragSurface_(newLoc);
// Scratch-specific: note possible illegal definition deletion for rollback below.
var isDeletingProcDef =
this.wouldDeleteBlock_ &&
this.draggingBlock_.type == Blockly.PROCEDURES_DEFINITION_BLOCK_TYPE;
var deleted = this.maybeDeleteBlock_();
if (!deleted) {
// 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);
this.fireMoveEvent_();
if (this.draggedConnectionManager_.wouldConnectBlock()) {
// Applying connections also rerenders the relevant blocks.
this.draggedConnectionManager_.applyConnections();
} else {
this.draggingBlock_.render();
}
this.draggingBlock_.scheduleSnapAndBump();
this.endTutorial();
} else if (this.workspace_.tutorialOn) {
this.setTutorial(true);
}
this.workspace_.setResizesEnabled(false); // not to move blocklyCanvas
var toolbox = this.workspace_.getToolbox();
if (toolbox) {
var style = this.draggingBlock_.isDeletable()
? 'blocklyToolboxDelete'
: 'blocklyToolboxGrab';
toolbox.removeStyle(style);
}
Blockly.Events.setGroup(false);
if (isOutside) {
var ws = this.workspace_;
// Reset a drag to outside of scratch-blocks
setTimeout(function () {
ws.undo();
});
}
// Scratch-specific: roll back deletes that create call blocks with defines.
// Have to wait for connections to be re-established, so put in setTimeout.
// Only do this if we deleted a proc def.
if (isDeletingProcDef) {
var ws = this.workspace_;
setTimeout(function () {
var allBlocks = ws.getAllBlocks();
for (var i = 0; i < allBlocks.length; i++) {
var block = allBlocks[i];
if (block.type == Blockly.PROCEDURES_CALL_BLOCK_TYPE) {
var procCode = block.getProcCode();
// Check for call blocks with no associated define block.
if (!Blockly.Procedures.getDefineBlock(procCode, ws)) {
alert(Blockly.Msg.PROCEDURE_USED);
ws.undo();
return; // There can only be one define deletion at a time.
}
}
}
// The proc deletion was valid, update the toolbox.
ws.refreshToolboxSelection_();
});
}
};
/**
* Start dragging a block. This includes moving it to the drag surface.
* @param {!goog.math.Coordinate} currentDragDeltaXY How far the pointer has
* moved from the position at mouse down, in pixel units.
* @package
*/
Blockly.CengageBlockDragger.prototype.startBlockDrag = function (
currentDragDeltaXY
) {
if (this.workspace_.tutorialOn) {
this.setTutorial(false);
}
if (!Blockly.Events.getGroup()) {
Blockly.Events.setGroup(true);
}
this.workspace_.setResizesEnabled(false);
Blockly.BlockAnimations.disconnectUiStop();
if (this.draggingBlock_.getParent()) {
this.draggingBlock_.unplug();
var delta = this.pixelsToWorkspaceUnits_(currentDragDeltaXY);
var newLoc = goog.math.Coordinate.sum(this.startXY_, delta);
this.draggingBlock_.translate(newLoc.x, newLoc.y);
Blockly.BlockAnimations.disconnectUiEffect(this.draggingBlock_);
}
this.draggingBlock_.setDragging(true);
// For future consideration: we may be able to put moveToDragSurface inside
// the block dragger, which would also let the block not track the block drag
// surface.
this.draggingBlock_.moveToDragSurface_();
var toolbox = this.workspace_.getToolbox();
if (toolbox) {
var style = this.draggingBlock_.isDeletable()
? 'blocklyToolboxDelete'
: 'blocklyToolboxGrab';
toolbox.addStyle(style);
}
};