Merge pull request #286 from nathan/block-state

Made blocks keep track of their full state when grabbed
This commit is contained in:
Nathan Dinsmore 2014-06-24 15:00:24 -04:00
commit b7a180ce8f
6 changed files with 77 additions and 25 deletions

View file

@ -95,8 +95,14 @@ public class Block extends Sprite {
private var indentTop:int = 2, indentBottom:int = 3;
private var indentLeft:int = 4, indentRight:int = 3;
public var wasInScriptsPane:Boolean;
private var originalX:int, originalY:int;
private static var ROLE_NONE:int = 0;
private static var ROLE_ABSOLUTE:int = 1;
private static var ROLE_EMBEDDED:int = 2;
private static var ROLE_NEXT:int = 3;
private static var ROLE_SUBSTACK1:int = 4;
private static var ROLE_SUBSTACK2:int = 5;
private var originalParent:DisplayObjectContainer, originalRole:int, originalIndex:int, originalPosition:Point;
public function Block(spec:String, type:String = " ", color:int = 0xD00000, op:* = 0, defaultArgs:Array = null) {
this.spec = Translator.map(spec);
@ -326,15 +332,58 @@ public class Block extends Sprite {
return [f];
}
public function saveOriginalPosition():void {
wasInScriptsPane = topBlock().parent is ScriptsPane;
originalX = x;
originalY = y;
public function saveOriginalState():void {
originalParent = parent;
if (parent) {
var b:Block = parent as Block;
if (b == null) {
originalRole = ROLE_ABSOLUTE;
} else if (isReporter) {
originalRole = ROLE_EMBEDDED;
originalIndex = b.args.indexOf(this);
} else if (b.nextBlock == this) {
originalRole = ROLE_NEXT;
} else if (b.subStack1 == this) {
originalRole = ROLE_SUBSTACK1;
} else if (b.subStack2 == this) {
originalRole = ROLE_SUBSTACK2;
}
originalPosition = localToGlobal(new Point(0, 0));
} else {
originalRole = ROLE_NONE;
originalPosition = null;
}
}
public function restoreOriginalPosition():void {
x = originalX;
y = originalY;
public function restoreOriginalState():void {
var b:Block = originalParent as Block;
switch (originalRole) {
case ROLE_NONE:
if (parent) parent.removeChild(this);
break;
case ROLE_ABSOLUTE:
originalParent.addChild(this);
var p:Point = originalParent.globalToLocal(originalPosition);
x = p.x;
y = p.y;
break;
case ROLE_EMBEDDED:
b.replaceArgWithBlock(b.args[originalIndex], this, Scratch.app.scriptsPane);
break;
case ROLE_NEXT:
b.insertBlock(this);
break;
case ROLE_SUBSTACK1:
b.insertBlockSub1(this);
break;
case ROLE_SUBSTACK2:
b.insertBlockSub2(this);
break;
}
}
public function originalPositionIn(p:DisplayObject):Point {
return originalPosition && p.globalToLocal(originalPosition);
}
private function setDefaultArgs(defaults:Array):void {
@ -751,9 +800,9 @@ public class Block extends Sprite {
if (isProcDef()) return; // don't duplicate procedure definition
var forStage:Boolean = Scratch.app.viewedObj() && Scratch.app.viewedObj().isStage;
var newStack:Block = BlockIO.stringToStack(BlockIO.stackToString(this), forStage);
newStack.x = x + deltaX;
newStack.y = y + deltaY;
parent.addChild(newStack);
var p:Point = localToGlobal(new Point(0, 0));
newStack.x = p.x + deltaX;
newStack.y = p.y + deltaY;
Scratch.app.gh.grabOnMouseUp(newStack);
}

View file

@ -1017,8 +1017,8 @@ public class ScratchRuntime {
} else if ((obj is Block) || (obj is ScratchComment)) {
app.selectSprite(prevOwner);
app.setTab('scripts');
obj.x = x;
obj.y = y;
obj.x = app.scriptsPane.padding;
obj.y = app.scriptsPane.padding;
if (obj is Block) obj.cacheAsBitmap = true;
app.scriptsPane.addChild(obj);
}

View file

@ -25,6 +25,7 @@
// creates a copy of that block when it is dragged out of the palette.
package ui {
import flash.geom.*;
import blocks.Block;
import interpreter.Interpreter;
import uiwidgets.*;
@ -67,7 +68,6 @@ public class BlockPalette extends ScrollFrameContents {
return false;
}
if (b.parent) b.parent.removeChild(b);
b.restoreOriginalPosition(); // restore position in case block is undeleted
Scratch.app.runtime.recordForUndelete(b, b.x, b.y, 0, Scratch.app.viewedObj());
app.scriptsPane.saveScripts();
app.updatePalette();

View file

@ -233,9 +233,10 @@ public class SpriteThumbnail extends Sprite {
if (obj is Block) {
// copy a block/stack to this sprite
if (targetObj == app.viewedObj()) return false; // dropped on my own thumbnail; do nothing
var b:Block = obj as Block;
b.restoreOriginalPosition();
targetObj.scripts.push(b.duplicate(false, targetObj.isStage));
var copy:Block = Block(obj).duplicate(false, targetObj.isStage);
copy.x = app.scriptsPane.padding;
copy.y = app.scriptsPane.padding;
targetObj.scripts.push(copy);
return false; // do not consume the original block
}
return false;

View file

@ -42,6 +42,7 @@ public class ScriptsPane extends ScrollFrameContents {
private const INSERT_WRAP:int = 4;
public var app:Scratch;
public var padding:int = 10;
private var viewedObj:ScratchObj;
private var commentLines:Shape;
@ -495,21 +496,20 @@ return true; // xxx disable this check for now; it was causing confusion at Scra
// 3. Compute the column widths
// 4. Move stacks into place
var pad:int = 10;
var stacks:Array = stacksSortedByX();
var columns:Array = assignStacksToColumns(stacks);
var columnWidths:Array = computeColumnWidths(columns);
var nextX:int = pad;
var nextX:int = padding;
for (var i:int = 0; i < columns.length; i++) {
var col:Array = columns[i];
var nextY:int = pad;
var nextY:int = padding;
for each (var b:Block in col) {
b.x = nextX;
b.y = nextY;
nextY += b.height + pad;
nextY += b.height + padding;
}
nextX += columnWidths[i] + pad;
nextX += columnWidths[i] + padding;
}
saveScripts();
}

View file

@ -412,7 +412,7 @@ public class GestureHandler {
if (obj is Block) {
var b:Block = Block(obj);
b.saveOriginalPosition();
b.saveOriginalState();
if (b.parent is Block) Block(b.parent).removeBlock(b);
if (b.parent != null) b.parent.removeChild(b);
app.scriptsPane.prepareToDrag(b);
@ -474,7 +474,9 @@ public class GestureHandler {
carriedObj.parent.removeChild(carriedObj);
if (!dropHandled(carriedObj, evt)) {
if (originalParent) { // put carriedObj back where it came from
if (carriedObj is Block) {
Block(carriedObj).restoreOriginalState();
} else if (originalParent) { // put carriedObj back where it came from
carriedObj.x = originalPosition.x;
carriedObj.y = originalPosition.y;
carriedObj.scaleX = carriedObj.scaleY = originalScale;