diff --git a/core/bubble.js b/core/bubble.js index e6a8ada2a..8e8023b03 100644 --- a/core/bubble.js +++ b/core/bubble.js @@ -283,43 +283,6 @@ Blockly.Bubble.prototype.bubbleMouseDown_ = function(e) { if (gesture) { gesture.handleBubbleStart(e, this); } - - // this.promote_(); - // Blockly.Bubble.unbindDragEvents_(); - // if (Blockly.utils.isRightButton(e)) { - // // No right-click. - // e.stopPropagation(); - // return; - // } else if (Blockly.utils.isTargetInput(e)) { - // // When focused on an HTML text input widget, don't trap any events. - // return; - // } - // // Left-click (or middle click) - // this.workspace_.startDrag(e, new goog.math.Coordinate( - // this.workspace_.RTL ? -this.relativeLeft_ : this.relativeLeft_, - // this.relativeTop_)); - - // Blockly.Bubble.onMouseUpWrapper_ = Blockly.bindEventWithChecks_(document, - // 'mouseup', this, Blockly.Bubble.bubbleMouseUp_); - // Blockly.Bubble.onMouseMoveWrapper_ = Blockly.bindEventWithChecks_(document, - // 'mousemove', this, this.bubbleMouseMove_); - // Blockly.hideChaff(); - // // This event has been handled. No need to bubble up to the document. - // e.stopPropagation(); -}; - -/** - * Drag this bubble to follow the mouse. - * @param {!Event} e Mouse move event. - * @private - */ -Blockly.Bubble.prototype.bubbleMouseMove_ = function(e) { - this.autoLayout_ = false; - var newXY = this.workspace_.moveDrag(e); - this.relativeLeft_ = this.workspace_.RTL ? -newXY.x : newXY.x; - this.relativeTop_ = newXY.y; - this.positionBubble_(); - this.renderArrow_(); }; /** @@ -453,6 +416,12 @@ Blockly.Bubble.prototype.positionBubble_ = function() { this.moveTo_(left, top); }; +/** + * Move the bubble group to the specified location in workspace coordinates. + * @param {number} x The x position to move to. + * @param {nubmer} y The y position to move to. + * @private + */ Blockly.Bubble.prototype.moveTo_ = function(x, y) { this.bubbleGroup_.setAttribute('transform', 'translate(' + x + ',' + y + ')'); }; @@ -604,42 +573,54 @@ Blockly.Bubble.prototype.dispose = function() { this.shape_ = null; }; +/** + * + * @package + */ Blockly.Bubble.prototype.moveToDragSurface = function(dragSurface) { - //var bubbleXY = this.getRelativeToSurfaceXY(); - //var anchorXY = this.getAnchorRelativeToSurfaceXY(); - - // TODO: check RTL. - var x = this.anchorXY_.x + this.relativeLeft_; - var y = this.anchorXY_.y + this.relativeTop_; - this.savedRelativeXY_ = - new goog.math.Coordinate(this.relativeLeft_, this.relativeTop_); - this.savedAnchorXY_ = this.anchorXY_; - this.moveTo_(0, 0); - dragSurface.translateSurface(x, y); - // Execute the move on the top-level SVG component. - dragSurface.setBlocksAndShow(this.bubbleGroup_); + this.autoLayout_ = false; + if (dragSurface) { + // TODO: check RTL. + var x = this.anchorXY_.x + this.relativeLeft_; + var y = this.anchorXY_.y + this.relativeTop_; + this.moveTo_(0, 0); + dragSurface.translateSurface(x, y); + // Execute the move on the top-level SVG component. + dragSurface.setBlocksAndShow(this.bubbleGroup_); + } }; +/** + * + * @package + */ Blockly.Bubble.prototype.moveDuringDrag = function(dragSurface, newLoc) { - console.log(newLoc); - dragSurface.translateSurface(newLoc.x, newLoc.y); - this.relativeLeft_ = this.savedRelativeXY_.x + newLoc.x; - this.relativeTop_ = this.savedRelativeXY_.y + newLoc.y; + if (dragSurface) { + dragSurface.translateSurface(newLoc.x, newLoc.y); + } else { + this.moveTo_(newLoc.x, newLoc.y); + } + this.relativeLeft_ = - this.anchorXY_.x + newLoc.x; + this.relativeTop_ = - this.anchorXY_.y + newLoc.y; this.renderArrow_(); }; +/** + * + * @package + */ Blockly.Bubble.prototype.moveOffDragSurface = function(dragSurface, newXY) { - - //this.savedAnchorXY_ = this.anchorXY_; - this.anchorXY_ = this.savedAnchorXY_; this.moveTo_(newXY.x, newXY.y); - dragSurface.clearAndHide(this.workspace_.getBubbleCanvas()); + if (dragSurface) { + dragSurface.clearAndHide(this.workspace_.getBubbleCanvas()); + } }; - +/** + * + * @package + */ Blockly.Bubble.prototype.getRelativeToSurfaceXY = function() { - // This may not be quite right. It's probably the top-left of the bubble - // group. return new goog.math.Coordinate(this.anchorXY_.x + this.relativeLeft_, this.anchorXY_.y + this.relativeTop_); }; diff --git a/core/bubble_dragger.js b/core/bubble_dragger.js index e66b500bf..c801233f3 100644 --- a/core/bubble_dragger.js +++ b/core/bubble_dragger.js @@ -26,14 +26,12 @@ goog.provide('Blockly.BubbleDragger'); -goog.require('Blockly.DraggedConnectionManager'); - goog.require('goog.math.Coordinate'); goog.require('goog.asserts'); /** - * Class for a block dragger. It moves blocks around the workspace when they + * Class for a bubble dragger. It moves bubbles around the workspace when they * are being dragged by a mouse or touch. * @param {!Blockly.Bubble} bubble The bubble to drag. * @param {!Blockly.WorkspaceSvg} workspace The workspace to drag on. @@ -41,8 +39,8 @@ goog.require('goog.asserts'); */ Blockly.BubbleDragger = function(bubble, workspace) { /** - * The top block in the stack that is being dragged. - * @type {!Blockly.BlockSvg} + * The bubble that is being dragged. + * @type {!Blockly.Bubble} * @private */ this.draggingBubble_ = bubble; @@ -55,32 +53,7 @@ Blockly.BubbleDragger = function(bubble, workspace) { this.workspace_ = workspace; /** - * Object that keeps track of connections on dragged blocks. - * @type {!Blockly.DraggedConnectionManager} - * @private - */ - this.draggedConnectionManager_ = null; - // new Blockly.DraggedConnectionManager( - // this.draggingBubble_); - - /** - * 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} - * @private - */ - this.deleteArea_ = null; - - /** - * Whether the block would be deleted if dropped immediately. - * @type {boolean} - * @private - */ - this.wouldDeleteBlock_ = false; - - /** - * The location of the top left corner of the dragging block at the beginning + * The location of the top left corner of the dragging bubble at the beginning * of the drag in workspace coordinates. * @type {!goog.math.Coordinate} * @private @@ -88,7 +61,9 @@ Blockly.BubbleDragger = function(bubble, workspace) { this.startXY_ = this.draggingBubble_.getRelativeToSurfaceXY(); // TODO: validate, getters, etc. - this.dragSurface_ = workspace.blockDragSurface_; + this.dragSurface_ = + Blockly.utils.is3dSupported() && !!workspace.blockDragSurface_ ? + workspace.blockDragSurface_ : null; }; /** @@ -99,47 +74,19 @@ Blockly.BubbleDragger.prototype.dispose = function() { this.draggingBubble_ = null; this.workspace_ = null; this.startWorkspace_ = null; - this.dragIconData_.length = 0; - - if (this.draggedConnectionManager_) { - this.draggedConnectionManager_.dispose(); - this.draggedConnectionManager_ = null; - } }; /** * 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.BubbleDragger.prototype.startBubbleDrag = function(currentDragDeltaXY) { - console.log('starting bubble drag'); +Blockly.BubbleDragger.prototype.startBubbleDrag = function() { if (!Blockly.Events.getGroup()) { Blockly.Events.setGroup(true); } this.workspace_.setResizesEnabled(false); - - // if (this.draggingBubble_.getParent()) { - // this.draggingBubble_.unplug(); - // var delta = this.pixelsToWorkspaceUnits_(currentDragDeltaXY); - // var newLoc = goog.math.Coordinate.sum(this.startXY_, delta); - - // this.draggingBubble_.translate(newLoc.x, newLoc.y); - // this.draggingBubble_.disconnectUiEffect(); - // } - //this.draggingBubble_.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.draggingBubble_.moveToDragSurface(this.dragSurface_); - - if (this.workspace_.toolbox_) { - var style = this.draggingBubble_.isDeletable() ? 'blocklyToolboxDelete' : - 'blocklyToolboxGrab'; - this.workspace_.toolbox_.addStyle(style); - } }; /** @@ -155,12 +102,8 @@ Blockly.BubbleDragger.prototype.dragBubble = function(e, currentDragDeltaXY) { var newLoc = goog.math.Coordinate.sum(this.startXY_, delta); this.draggingBubble_.moveDuringDrag(this.dragSurface_, newLoc); - //this.dragIcons_(delta); - - this.deleteArea_ = this.workspace_.isDeleteArea(e); - //this.draggedConnectionManager_.update(delta, this.deleteArea_); - - //this.updateCursorDuringBubbleDrag_(); + // TODO (fenichel): Possibly update the cursor if dragging to the trash can + // is allowed. }; /** @@ -173,31 +116,14 @@ Blockly.BubbleDragger.prototype.dragBubble = function(e, currentDragDeltaXY) { Blockly.BubbleDragger.prototype.endBubbleDrag = function(e, currentDragDeltaXY) { // Make sure internal state is fresh. this.dragBubble(e, currentDragDeltaXY); - this.dragIconData_ = []; - - Blockly.BlockSvg.disconnectUiStop_(); var delta = this.pixelsToWorkspaceUnits_(currentDragDeltaXY); var newLoc = goog.math.Coordinate.sum(this.startXY_, delta); this.draggingBubble_.moveOffDragSurface(this.dragSurface_, newLoc); - var deleted = true;//this.maybeDeleteBlock_(); - if (!deleted) { - // These are expensive and don't need to be done if we're deleting. - this.draggingBubble_.moveConnections_(delta.x, delta.y); - this.draggingBubble_.setDragging(false); - //this.draggedConnectionManager_.applyConnections(); - this.draggingBubble_.render(); - this.fireMoveEvent_(); - this.draggingBubble_.scheduleSnapAndBump(); - } + this.fireMoveEvent_(); this.workspace_.setResizesEnabled(true); - if (this.workspace_.toolbox_) { - var style = this.draggingBubble_.isDeletable() ? 'blocklyToolboxDelete' : - 'blocklyToolboxGrab'; - this.workspace_.toolbox_.removeStyle(style); - } Blockly.Events.setGroup(false); }; @@ -206,54 +132,8 @@ Blockly.BubbleDragger.prototype.endBubbleDrag = function(e, currentDragDeltaXY) * @private */ Blockly.BubbleDragger.prototype.fireMoveEvent_ = function() { - var event = new Blockly.Events.BlockMove(this.draggingBubble_); - event.oldCoordinate = this.startXY_; - event.recordNew(); - 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.BubbleDragger.prototype.maybeDeleteBubble_ = function() { - var trashcan = this.workspace_.trashcan; - - if (this.wouldDeleteBlock_) { - if (trashcan) { - goog.Timer.callOnce(trashcan.close, 100, trashcan); - } - // 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 is closed. - trashcan.close(); - } - 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.BubbleDragger.prototype.updateCursorDuringBubbleDrag_ = function() { - this.wouldDeleteBlock_ = false; //this.draggedConnectionManager_.wouldDeleteBlock(); - var trashcan = this.workspace_.trashcan; - if (this.wouldDeleteBlock_) { - this.draggingBubble_.setDeleteStyle(true); - if (this.deleteArea_ == Blockly.DELETE_AREA_TRASH && trashcan) { - trashcan.setOpen_(true); - } - } else { - this.draggingBubble_.setDeleteStyle(false); - if (trashcan) { - trashcan.setOpen_(false); - } - } + // TODO: move events for comments. + return; }; /** diff --git a/core/gesture.js b/core/gesture.js index f7b9262ce..6c222ddfb 100644 --- a/core/gesture.js +++ b/core/gesture.js @@ -455,7 +455,7 @@ Blockly.Gesture.prototype.startDraggingBlock_ = function() { Blockly.Gesture.prototype.startDraggingBubble_ = function() { this.bubbleDragger_ = new Blockly.BubbleDragger(this.startBubble_, this.startWorkspace_); - this.bubbleDragger_.startBubbleDrag(this.currentDragDeltaXY_); + this.bubbleDragger_.startBubbleDrag(); this.bubbleDragger_.dragBubble(this.mostRecentEvent_, this.currentDragDeltaXY_); }; @@ -566,6 +566,9 @@ Blockly.Gesture.prototype.handleUp = function(e) { this.blockDragger_.endBlockDrag(e, this.currentDragDeltaXY_); } else if (this.isDraggingWorkspace_) { this.workspaceDragger_.endDrag(this.currentDragDeltaXY_); + } else if (this.isBubbleClick_()) { + // Bubbles are in front of all fields and blocks. + this.doBubbleClick_(); } else if (this.isFieldClick_()) { this.doFieldClick_(); } else if (this.isBlockClick_()) { @@ -687,6 +690,15 @@ Blockly.Gesture.prototype.handleBubbleStart = function(e, bubble) { * of target. Any developer wanting to add behaviour on clicks should modify * only this code. */ +/** + * Execute a bubble click. + * @private + */ +Blockly.Gesture.prototype.doBubbleClick_ = function() { + // TODO: This isn't really enough, is it. + this.startBubble_.promote_(); +}; + /** * Execute a field click. * @private @@ -831,6 +843,18 @@ Blockly.Gesture.prototype.setStartFlyout_ = function(flyout) { /* Begin helper functions defining types of clicks. Any developer wanting * to change the definition of a click should modify only this code. */ +/** + * Whether this gesture is a click on a bubble. This should only be called when + * ending a gesture (mouse up, touch end). + * @return {boolean} whether this gesture was a click on a bubble. + * @private + */ +Blockly.Gesture.prototype.isBubbleClick_ = function() { + // A bubble click starts on a bubble and never escapes the drag radius. + var hasStartBubble = !!this.startBubble_; + return hasStartBubble && !this.hasExceededDragRadius_; +}; + /** * Whether this gesture is a click on a block. This should only be called when * ending a gesture (mouse up, touch end).