summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--blocks.js12
-rw-r--r--gui.js9
-rwxr-xr-xhistory.txt8
-rw-r--r--objects.js69
-rw-r--r--store.js21
5 files changed, 88 insertions, 31 deletions
diff --git a/blocks.js b/blocks.js
index 279acb7..6ab6781 100644
--- a/blocks.js
+++ b/blocks.js
@@ -155,7 +155,7 @@ DialogBoxMorph, BlockInputFragmentMorph, PrototypeHatBlockMorph, Costume*/
// Global stuff ////////////////////////////////////////////////////////
-modules.blocks = '2014-July-18';
+modules.blocks = '2014-July-29';
var SyntaxElementMorph;
@@ -2093,7 +2093,15 @@ BlockMorph.prototype.userMenu = function () {
menu.addItem(
"duplicate",
function () {
- this.fullCopy().pickUp(world);
+ var dup = myself.fullCopy(),
+ ide = myself.parentThatIsA(IDE_Morph);
+ dup.pickUp(world);
+ if (ide) {
+ world.hand.grabOrigin = {
+ origin: ide.palette,
+ position: ide.palette.center()
+ };
+ }
},
'make a copy\nand pick it up'
);
diff --git a/gui.js b/gui.js
index 7e38095..e4c75dd 100644
--- a/gui.js
+++ b/gui.js
@@ -69,7 +69,7 @@ SpeechBubbleMorph*/
// Global stuff ////////////////////////////////////////////////////////
-modules.gui = '2014-July-25';
+modules.gui = '2014-July-29';
// Declarations
@@ -1824,12 +1824,9 @@ IDE_Morph.prototype.paintNewSprite = function () {
IDE_Morph.prototype.duplicateSprite = function (sprite) {
var duplicate = sprite.fullCopy();
- duplicate.name = this.newSpriteName(sprite.name);
duplicate.setPosition(this.world().hand.position());
- this.stage.add(duplicate);
+ duplicate.appearIn(this);
duplicate.keepWithin(this.stage);
- this.sprites.add(duplicate);
- this.corral.addSprite(duplicate);
this.selectSprite(duplicate);
};
@@ -2853,7 +2850,7 @@ IDE_Morph.prototype.exportGlobalBlocks = function () {
};
IDE_Morph.prototype.exportSprite = function (sprite) {
- var str = this.serializer.serialize(sprite);
+ var str = this.serializer.serialize(sprite.allParts());
window.open('data:text/xml,<sprites app="'
+ this.serializer.app
+ '" version="'
diff --git a/history.txt b/history.txt
index 0caf24b..b05d24a 100755
--- a/history.txt
+++ b/history.txt
@@ -2238,3 +2238,11 @@ ______
------
* Lists: fixed "Load Failed Type Error Cannot read property 'isLinked' of null"
* Threads: enable “JS function” block to create custom control structures and HOFs
+
+140729
+------
+* fixed #526, thanks, Bernat, for reporting it!
+* Objects, GUI: duplicate and clone nested sprites
+* GUI, Store: export and import nested sprites
+* Objects: double clicking on a sprite in the stage selects it in the IDE
+* Objects: added ‘move’ option to the sprite context menu, lets the user move (nested) sprites in edit mode without changing their layering, and also sprites marked “undraggable”
diff --git a/objects.js b/objects.js
index f9908ef..c4c4eb8 100644
--- a/objects.js
+++ b/objects.js
@@ -125,7 +125,7 @@ PrototypeHatBlockMorph*/
// Global stuff ////////////////////////////////////////////////////////
-modules.objects = '2014-July-25';
+modules.objects = '2014-July-29';
var SpriteMorph;
var StageMorph;
@@ -1338,6 +1338,7 @@ SpriteMorph.prototype.fullCopy = function () {
var c = SpriteMorph.uber.fullCopy.call(this),
myself = this,
arr = [],
+ dp,
cb;
c.stopTalking();
@@ -1348,7 +1349,6 @@ SpriteMorph.prototype.fullCopy = function () {
c.scripts.owner = c;
c.variables = this.variables.copy();
c.variables.owner = c;
-
c.customBlocks = [];
this.customBlocks.forEach(function (def) {
cb = def.copyAndBindTo(c);
@@ -1370,15 +1370,31 @@ SpriteMorph.prototype.fullCopy = function () {
arr.push(sound);
});
c.sounds = new List(arr);
-
- c.parts = [];
- c.anchor = null;
c.nestingScale = 1;
c.rotatesWithAnchor = true;
+ c.anchor = null;
+ c.parts = [];
+ this.parts.forEach(function (part) {
+ dp = part.fullCopy();
+ dp.nestingScale = part.nestingScale;
+ dp.rotatesWithAnchor = part.rotatesWithAnchor;
+ c.attachPart(dp);
+ });
return c;
};
+SpriteMorph.prototype.appearIn = function (ide) {
+ // private - used in IDE_Morph.duplicateSprite()
+ this.name = ide.newSpriteName(this.name);
+ ide.stage.add(this);
+ ide.sprites.add(this);
+ ide.corral.addSprite(this);
+ this.parts.forEach(function (part) {
+ part.appearIn(ide);
+ });
+};
+
// SpriteMorph versioning
SpriteMorph.prototype.setName = function (string) {
@@ -2602,6 +2618,7 @@ SpriteMorph.prototype.userMenu = function () {
}
menu.addItem("duplicate", 'duplicate');
menu.addItem("delete", 'remove');
+ menu.addItem("move", 'move');
menu.addItem("edit", 'edit');
menu.addLine();
if (this.anchor) {
@@ -2626,7 +2643,7 @@ SpriteMorph.prototype.exportSprite = function () {
SpriteMorph.prototype.edit = function () {
var ide = this.parentThatIsA(IDE_Morph);
- if (ide) {
+ if (ide && !ide.isAppMode) {
ide.selectSprite(this);
}
};
@@ -2657,25 +2674,29 @@ SpriteMorph.prototype.remove = function () {
// SpriteMorph cloning (experimental)
SpriteMorph.prototype.createClone = function () {
- var clone,
- hats,
- stage = this.parentThatIsA(StageMorph);
- if (stage) {
- if (stage.cloneCount > 300) {return; }
- stage.cloneCount += 1;
- clone = this.fullCopy();
- clone.isClone = true;
- clone.name = '';
- clone.cloneOriginName = this.isClone ?
- this.cloneOriginName : this.name;
- stage.add(clone);
- hats = clone.allHatBlocksFor('__clone__init__');
- hats.forEach(function (block) {
- stage.threads.startProcess(block, stage.isThreadSafe);
- });
+ var stage = this.parentThatIsA(StageMorph);
+ if (stage && stage.cloneCount <= 300) {
+ this.fullCopy().clonify(stage);
}
};
+SpriteMorph.prototype.clonify = function (stage) {
+ var hats;
+ this.parts.forEach(function (part) {
+ part.clonify(stage);
+ });
+ stage.cloneCount += 1;
+ this.cloneOriginName = this.isClone ?
+ this.cloneOriginName : this.name;
+ this.isClone = true;
+ this.name = '';
+ stage.add(this);
+ hats = this.allHatBlocksFor('__clone__init__');
+ hats.forEach(function (block) {
+ stage.threads.startProcess(block, stage.isThreadSafe);
+ });
+};
+
SpriteMorph.prototype.removeClone = function () {
if (this.isClone) {
// this.stopTalking();
@@ -3464,6 +3485,10 @@ SpriteMorph.prototype.mouseClickLeft = function () {
return procs;
};
+SpriteMorph.prototype.mouseDoubleClick = function () {
+ this.edit();
+};
+
// SpriteMorph timer
SpriteMorph.prototype.getTimer = function () {
diff --git a/store.js b/store.js
index 11e2757..f8d46bf 100644
--- a/store.js
+++ b/store.js
@@ -61,7 +61,7 @@ SyntaxElementMorph*/
// Global stuff ////////////////////////////////////////////////////////
-modules.store = '2014-Jun-04';
+modules.store = '2014-July-29';
// XML_Serializer ///////////////////////////////////////////////////////
@@ -618,6 +618,25 @@ SnapSerializer.prototype.loadSprites = function (xmlString, ide) {
sprite.gotoXY(+model.attributes.x || 0, +model.attributes.y || 0);
myself.loadObject(sprite, model);
});
+
+ // restore nesting associations
+ project.stage.children.forEach(function (sprite) {
+ var anchor;
+ if (sprite.nestingInfo) { // only sprites may have nesting info
+ anchor = project.sprites[sprite.nestingInfo.anchor];
+ if (anchor) {
+ anchor.attachPart(sprite);
+ }
+ sprite.rotatesWithAnchor = (sprite.nestingInfo.synch === 'true');
+ }
+ });
+ project.stage.children.forEach(function (sprite) {
+ if (sprite.nestingInfo) { // only sprites may have nesting info
+ sprite.nestingScale = +(sprite.nestingInfo.scale || sprite.scale);
+ delete sprite.nestingInfo;
+ }
+ });
+
this.objects = {};
this.project = {};
this.mediaDict = {};