From c9169285d94cc68c99b91b9bd8d360696d0f3f09 Mon Sep 17 00:00:00 2001 From: Neil Fraser Date: Tue, 2 Dec 2014 15:00:10 -0800 Subject: [PATCH] Add red 'X' to mouse cursor if blocks are over toolbox. --- blockly_compressed.js | 17 +++++++++-------- blockly_uncompressed.js | 2 +- core/block.js | 1 + core/css.js | 17 ++++++++++++++--- core/toolbox.js | 21 +++++++++++++++++++++ core/workspace.js | 2 ++ 6 files changed, 48 insertions(+), 12 deletions(-) diff --git a/blockly_compressed.js b/blockly_compressed.js index dc3600847..a501272ac 100644 --- a/blockly_compressed.js +++ b/blockly_compressed.js @@ -907,7 +907,7 @@ Blockly.Workspace.prototype.traceOn=function(a){this.traceOn_=a;this.traceWrappe Blockly.Workspace.prototype.highlightBlock=function(a){this.traceOn_&&0!=Blockly.Block.dragMode_&&this.traceOn(!1);if(this.traceOn_){var b=null;if(a&&(b=this.getBlockById(a),!b))return;this.traceOn(!1);b?b.select():Blockly.selected&&Blockly.selected.unselect();var c=this;setTimeout(function(){c.traceOn(!0)},1)}}; Blockly.Workspace.prototype.fireChangeEvent=function(){this.fireChangeEventPid_&&window.clearTimeout(this.fireChangeEventPid_);var a=this.svgBlockCanvas_;a&&(this.fireChangeEventPid_=window.setTimeout(function(){Blockly.fireUiEvent(a,"blocklyWorkspaceChange")},0))}; Blockly.Workspace.prototype.paste=function(a){if(!(a.getElementsByTagName("block").length>=this.remainingCapacity())){var b=Blockly.Xml.domToBlock(this,a),c=parseInt(a.getAttribute("x"),10);a=parseInt(a.getAttribute("y"),10);if(!isNaN(c)&&!isNaN(a)){Blockly.RTL&&(c=-c);do for(var d=!1,e=this.getAllBlocks(),f=0,g;g=e[f];f++)g=g.getRelativeToSurfaceXY(),1>=Math.abs(c-g.x)&&1>=Math.abs(a-g.y)&&(c=Blockly.RTL?c-Blockly.SNAP_RADIUS:c+Blockly.SNAP_RADIUS,a+=2*Blockly.SNAP_RADIUS,d=!0);while(d);b.moveBy(c, -a)}b.select()}};Blockly.Workspace.prototype.remainingCapacity=function(){return Infinity==this.maxBlocks?Infinity:this.maxBlocks-this.getAllBlocks().length};Blockly.Workspace.prototype.recordDeleteAreas=function(){this.deleteAreaTrash_=this.trashcan?this.trashcan.getRect():null;this.deleteAreaToolbox_=this.flyout_?this.flyout_.getRect():null}; +a)}b.select()}};Blockly.Workspace.prototype.remainingCapacity=function(){return Infinity==this.maxBlocks?Infinity:this.maxBlocks-this.getAllBlocks().length};Blockly.Workspace.prototype.recordDeleteAreas=function(){this.deleteAreaTrash_=this.trashcan?this.trashcan.getRect():null;this.deleteAreaToolbox_=this.flyout_?this.flyout_.getRect():this.toolbox_?this.toolbox_.getRect():null}; Blockly.Workspace.prototype.isDeleteArea=function(a){a=Blockly.mouseToSvg(a);a=new goog.math.Coordinate(a.x,a.y);if(this.deleteAreaTrash_){if(this.deleteAreaTrash_.contains(a))return this.trashcan.setOpen_(!0),Blockly.Css.setCursor(Blockly.Css.Cursor.DELETE),!0;this.trashcan.setOpen_(!1)}if(this.deleteAreaToolbox_&&this.deleteAreaToolbox_.contains(a))return Blockly.Css.setCursor(Blockly.Css.Cursor.DELETE),!0;Blockly.Css.setCursor(Blockly.Css.Cursor.CLOSED);return!1}; Blockly.Workspace.prototype.clear=Blockly.Workspace.prototype.clear; // Copyright 2012 Google Inc. Apache License 2.0 @@ -1042,7 +1042,7 @@ Blockly.Block.prototype.getHeightWidth=function(){var a=this.svg_.height,b=this. Blockly.Block.prototype.onMouseDown_=function(a){if(!this.isInFlyout){Blockly.svgResize();Blockly.terminateDrag_();this.select();Blockly.hideChaff();if(Blockly.isRightButton(a))this.showContextMenu_(a);else if(this.isMovable()){Blockly.removeAllRanges();Blockly.Css.setCursor(Blockly.Css.Cursor.CLOSED);var b=this.getRelativeToSurfaceXY();this.startDragX=b.x;this.startDragY=b.y;this.startDragMouseX=a.clientX;this.startDragMouseY=a.clientY;Blockly.Block.dragMode_=1;Blockly.Block.onMouseUpWrapper_=Blockly.bindEvent_(document, "mouseup",this,this.onMouseUp_);Blockly.Block.onMouseMoveWrapper_=Blockly.bindEvent_(document,"mousemove",this,this.onMouseMove_);this.draggedBubbles_=[];for(var b=this.getDescendants(),c=0,d;d=b[c];c++){d=d.getIcons();for(var e=0;ethis.workspace.remainingCapacity()&&(d.enabled=!1);c.push(d);this.isEditable()&&!this.collapsed_&&Blockly.comments&&(d={enabled:!0},this.comment?(d.text=Blockly.Msg.REMOVE_COMMENT,d.callback=function(){b.setCommentText(null)}): (d.text=Blockly.Msg.ADD_COMMENT,d.callback=function(){b.setCommentText("")}),c.push(d));if(!this.collapsed_)for(d=0;d>>/g,Blockly.Css.mediaPath_);goog.cssom.addCssText(a);a=goog.cssom.getAllCssStyleSheets();Blockly.Css.styleSheet_=a[a.length-1];Blockly.Css.setCursor("handopen")}; -Blockly.Css.setCursor=function(a){if(!Blockly.readOnly&&Blockly.Css.currentCursor_!=a){Blockly.Css.currentCursor_=a;var b="url("+Blockly.Css.mediaPath_+"/"+a+".cur) "+(a==Blockly.Css.Cursor.OPEN?"8 5":"7 3")+", auto";goog.cssom.replaceCssRule("",".blocklyDraggable {\n cursor: "+b+";\n}\n",Blockly.Css.styleSheet_,0);Blockly.svg&&(Blockly.svg.style.cursor=a==Blockly.Css.Cursor.OPEN?"":b)}}; -Blockly.Css.CONTENT=[".blocklyDraggable {","}",".blocklySvg {"," background-color: #fff;"," border: 1px solid #ddd;"," overflow: hidden;","}",".blocklyWidgetDiv {"," position: absolute;"," display: none;"," z-index: 999;","}",".blocklyResizeSE {"," fill: #aaa;"," cursor: se-resize;","}",".blocklyResizeSW {"," fill: #aaa;"," cursor: sw-resize;","}",".blocklyResizeLine {"," stroke-width: 1;"," stroke: #888;","}",".blocklyHighlightedConnectionPath {"," stroke-width: 4px;"," stroke: #fc3;", -" fill: none;","}",".blocklyPathLight {"," fill: none;"," stroke-width: 2;"," stroke-linecap: round;","}",".blocklySelected>.blocklyPath {"," stroke-width: 3px;"," stroke: #fc3;","}",".blocklySelected>.blocklyPathLight {"," display: none;","}",".blocklyDragging>.blocklyPath,",".blocklyDragging>.blocklyPathLight {"," fill-opacity: .8;"," stroke-opacity: .8;","}",".blocklyDragging>.blocklyPathDark {"," display: none;","}",".blocklyDisabled>.blocklyPath {"," fill-opacity: .5;"," stroke-opacity: .5;", -"}",".blocklyDisabled>.blocklyPathLight,",".blocklyDisabled>.blocklyPathDark {"," display: none;","}",".blocklyText {"," cursor: default;"," font-family: sans-serif;"," font-size: 11pt;"," fill: #fff;","}",".blocklyNonEditableText>text {"," pointer-events: none;","}",".blocklyNonEditableText>rect,",".blocklyEditableText>rect {"," fill: #fff;"," fill-opacity: .6;","}",".blocklyNonEditableText>text,",".blocklyEditableText>text {"," fill: #000;","}",".blocklyEditableText:hover>rect {"," stroke-width: 2;", +Blockly.Css={};Blockly.Css.Cursor={OPEN:"handopen",CLOSED:"handclosed",DELETE:"handdelete"};Blockly.Css.currentCursor_="";Blockly.Css.styleSheet_=null;Blockly.Css.mediaPath_="";Blockly.Css.inject=function(){var a=Blockly.Css.CONTENT.join("\n");Blockly.Css.mediaPath_=Blockly.pathToMedia.replace(/[\\\/]$/,"");a=a.replace(/<<>>/g,Blockly.Css.mediaPath_);goog.cssom.addCssText(a);a=goog.cssom.getAllCssStyleSheets();Blockly.Css.styleSheet_=a[a.length-1];Blockly.Css.setCursor(Blockly.Css.Cursor.OPEN)}; +Blockly.Css.setCursor=function(a){if(!Blockly.readOnly&&Blockly.Css.currentCursor_!=a){Blockly.Css.currentCursor_=a;var b="url("+Blockly.Css.mediaPath_+"/"+a+".cur) "+(a==Blockly.Css.Cursor.OPEN?"8 5":"7 3")+", auto";goog.cssom.replaceCssRule("",".blocklyDraggable {\n cursor: "+b+";\n}\n",Blockly.Css.styleSheet_,0);for(var c=document.getElementsByClassName("blocklyToolboxDiv"),d=0,e;e=c[d];d++)e.style.cursor=a==Blockly.Css.Cursor.OPEN?"":b;Blockly.svg&&(Blockly.svg.style.cursor=a==Blockly.Css.Cursor.OPEN? +"":b)}}; +Blockly.Css.CONTENT=[".blocklyDraggable {","}",".blocklySvg {"," background-color: #fff;"," border: 1px solid #ddd;"," overflow: hidden;","}",".blocklyWidgetDiv {"," position: absolute;"," display: none;"," z-index: 999;","}",".blocklyResizeSE {"," fill: #aaa;"," cursor: se-resize;","}",".blocklyResizeSW {"," fill: #aaa;"," cursor: sw-resize;","}",".blocklyResizeLine {"," stroke-width: 1;"," stroke: #888;","}",".blocklyHighlightedConnectionPath {"," stroke-width: 4px;"," stroke: #fc3;"," fill: none;", +"}",".blocklyPathLight {"," fill: none;"," stroke-width: 2;"," stroke-linecap: round;","}",".blocklySelected>.blocklyPath {"," stroke-width: 3px;"," stroke: #fc3;","}",".blocklySelected>.blocklyPathLight {"," display: none;","}",".blocklyDragging>.blocklyPath,",".blocklyDragging>.blocklyPathLight {"," fill-opacity: .8;"," stroke-opacity: .8;","}",".blocklyDragging>.blocklyPathDark {"," display: none;","}",".blocklyDisabled>.blocklyPath {"," fill-opacity: .5;"," stroke-opacity: .5;","}", +".blocklyDisabled>.blocklyPathLight,",".blocklyDisabled>.blocklyPathDark {"," display: none;","}",".blocklyText {"," cursor: default;"," font-family: sans-serif;"," font-size: 11pt;"," fill: #fff;","}",".blocklyNonEditableText>text {"," pointer-events: none;","}",".blocklyNonEditableText>rect,",".blocklyEditableText>rect {"," fill: #fff;"," fill-opacity: .6;","}",".blocklyNonEditableText>text,",".blocklyEditableText>text {"," fill: #000;","}",".blocklyEditableText:hover>rect {"," stroke-width: 2;", " stroke: #fff;","}",".blocklyBubbleText {"," fill: #000;","}",".blocklySvg text {"," -moz-user-select: none;"," -webkit-user-select: none;"," user-select: none;"," cursor: inherit;","}",".blocklyHidden {"," display: none;","}",".blocklyFieldDropdown:not(.blocklyHidden) {"," display: block;","}",".blocklyTooltipBackground {"," fill: #ffffc7;"," stroke-width: 1px;"," stroke: #d8d8d8;","}",".blocklyTooltipShadow,",".blocklyDropdownMenuShadow {"," fill: #bbb;"," filter: url(#blocklyShadowFilter);", "}",".blocklyTooltipText {"," font-family: sans-serif;"," font-size: 9pt;"," fill: #000;","}",".blocklyIconShield {"," cursor: default;"," fill: #00c;"," stroke-width: 1px;"," stroke: #ccc;","}",".blocklyIconGroup:hover>.blocklyIconShield {"," fill: #00f;"," stroke: #fff;","}",".blocklyIconGroup:hover>.blocklyIconMark {"," fill: #fff;","}",".blocklyIconMark {"," cursor: default !important;"," font-family: sans-serif;"," font-size: 9pt;"," font-weight: bold;"," fill: #ccc;"," text-anchor: middle;", "}",".blocklyWarningBody {","}",".blocklyMinimalBody {"," margin: 0;"," padding: 0;","}",".blocklyCommentTextarea {"," margin: 0;"," padding: 2px;"," border: 0;"," resize: none;"," background-color: #ffc;","}",".blocklyHtmlInput {"," font-family: sans-serif;"," font-size: 11pt;"," border: none;"," outline: none;"," width: 100%","}",".blocklyMutatorBackground {"," fill: #fff;"," stroke-width: 1;"," stroke: #ddd;","}",".blocklyFlyoutBackground {"," fill: #ddd;"," fill-opacity: .8;", diff --git a/blockly_uncompressed.js b/blockly_uncompressed.js index fe6daf2b2..f4927cfaa 100644 --- a/blockly_uncompressed.js +++ b/blockly_uncompressed.js @@ -54,7 +54,7 @@ goog.addDependency("../../../" + dir + "/core/procedures.js", ['Blockly.Procedur goog.addDependency("../../../" + dir + "/core/realtime-client-utils.js", ['rtclient'], []); goog.addDependency("../../../" + dir + "/core/realtime.js", ['Blockly.Realtime'], ['goog.array', 'goog.dom', 'goog.style', 'rtclient']); goog.addDependency("../../../" + dir + "/core/scrollbar.js", ['Blockly.Scrollbar', 'Blockly.ScrollbarPair'], ['goog.userAgent']); -goog.addDependency("../../../" + dir + "/core/toolbox.js", ['Blockly.Toolbox'], ['Blockly.Flyout', 'goog.events.BrowserFeature', 'goog.html.SafeHtml', 'goog.style', 'goog.ui.tree.TreeControl', 'goog.ui.tree.TreeNode']); +goog.addDependency("../../../" + dir + "/core/toolbox.js", ['Blockly.Toolbox'], ['Blockly.Flyout', 'goog.events.BrowserFeature', 'goog.html.SafeHtml', 'goog.style', 'goog.ui.tree.TreeControl', 'goog.ui.tree.TreeNode', 'goog.math.Rect']); goog.addDependency("../../../" + dir + "/core/tooltip.js", ['Blockly.Tooltip'], []); goog.addDependency("../../../" + dir + "/core/trashcan.js", ['Blockly.Trashcan'], ['goog.math', 'goog.math.Rect', 'goog.Timer']); goog.addDependency("../../../" + dir + "/core/utils.js", ['Blockly.utils'], []); diff --git a/core/block.js b/core/block.js index 9fcfd9a08..76133da89 100644 --- a/core/block.js +++ b/core/block.js @@ -592,6 +592,7 @@ Blockly.Block.prototype.onMouseUp_ = function(e) { Blockly.highlightedConnection_.unhighlight(); Blockly.highlightedConnection_ = null; } + Blockly.Css.setCursor(Blockly.Css.Cursor.OPEN); }); }; diff --git a/core/css.js b/core/css.js index 37fa2e665..324a6f743 100644 --- a/core/css.js +++ b/core/css.js @@ -74,7 +74,7 @@ Blockly.Css.inject = function() { goog.cssom.addCssText(text); var sheets = goog.cssom.getAllCssStyleSheets(); Blockly.Css.styleSheet_ = sheets[sheets.length - 1]; - Blockly.Css.setCursor('handopen'); + Blockly.Css.setCursor(Blockly.Css.Cursor.OPEN); }; /** @@ -98,11 +98,22 @@ Blockly.Css.setCursor = function(cursor) { } var url = 'url(' + Blockly.Css.mediaPath_ + '/' + cursor + '.cur) ' + xy + ', auto'; + // There are potentially hundreds of draggable objects. Changing their style + // properties individually is too slow, so change the CSS rule instead. var rule = '.blocklyDraggable {\n cursor: ' + url + ';\n}\n'; goog.cssom.replaceCssRule('', rule, Blockly.Css.styleSheet_, 0); + // There is probably only one toolbox, so just change its style property. + var toolboxen = document.getElementsByClassName('blocklyToolboxDiv'); + for (var i = 0, toolbox; toolbox = toolboxen[i]; i++) { + if (cursor == Blockly.Css.Cursor.OPEN) { + toolbox.style.cursor = ''; + } else { + toolbox.style.cursor = url; + } + } + // Set cursor on the SVG surface as well, so that rapid movements + // don't result in cursor changing to an arrow momentarily. if (Blockly.svg) { - // Set cursor on the SVG surface as well, so that rapid movements - // don't result in cursor changing to an arrow momentarily. if (cursor == Blockly.Css.Cursor.OPEN) { Blockly.svg.style.cursor = ''; } else { diff --git a/core/toolbox.js b/core/toolbox.js index 3debd6e8b..1948805ea 100644 --- a/core/toolbox.js +++ b/core/toolbox.js @@ -32,6 +32,7 @@ goog.require('goog.html.SafeHtml'); goog.require('goog.style'); goog.require('goog.ui.tree.TreeControl'); goog.require('goog.ui.tree.TreeNode'); +goog.require('goog.math.Rect'); /** @@ -197,6 +198,26 @@ Blockly.Toolbox.prototype.clearSelection = function() { this.tree_.setSelectedItem(null); }; +/** + * Return the deletion rectangle for this toolbar. + * @return {goog.math.Rect} Rectangle in which to delete. + */ +Blockly.Toolbox.prototype.getRect = function() { + // BIG_NUM is offscreen padding so that blocks dragged beyond the toolbox + // area are still deleted. Must be smaller than Infinity, but larger than + // the largest screen size. + var BIG_NUM = 10000000; + // Assumes that the toolbox is on the SVG edge. If this changes + // (e.g. toolboxes in mutators) then this code will need to be more complex. + if (Blockly.RTL) { + var svgSize = Blockly.svgSize(); + var x = svgSize.width - this.width; + } else { + var x = -BIG_NUM; + } + return new goog.math.Rect(x, -BIG_NUM, BIG_NUM + this.width, 2 * BIG_NUM); +}; + // Extending Closure's Tree UI. /** diff --git a/core/workspace.js b/core/workspace.js index 6babbeaa0..a129bd9fc 100644 --- a/core/workspace.js +++ b/core/workspace.js @@ -412,6 +412,8 @@ Blockly.Workspace.prototype.recordDeleteAreas = function() { } if (this.flyout_) { this.deleteAreaToolbox_ = this.flyout_.getRect(); + } else if (this.toolbox_) { + this.deleteAreaToolbox_ = this.toolbox_.getRect(); } else { this.deleteAreaToolbox_ = null; }