diff --git a/HISTORY.md b/HISTORY.md
index fb9539f5..5e297567 100755
--- a/HISTORY.md
+++ b/HISTORY.md
@@ -13,6 +13,7 @@
* blocks for changing and querying the "flat line ends" setting
* selectors for changing and querying "draggable" and "rotation style" settings
* special context-aware drop-downs for custom blocks
+ * new "stick to" submenu in the sprite context menu where applicable
* multi-line and monospaced "code" input slots for custom blocks
* new "string" library, thanks, Brian
* added "neg" selector to monadic function reporter in "Operators" category
@@ -39,6 +40,9 @@
* Greek, thanks, Alexandros!
* German
+### 2019-02-18
+* Objects: enable sprite nesting via the context menu
+
### 2019-02-15
* BYOB: tweaked yesterday's fix...
* Blocks: fixed a glitch in the custom block help mechanism (show only the prototype)
diff --git a/snap.html b/snap.html
index 27489386..af63bb3c 100755
--- a/snap.html
+++ b/snap.html
@@ -8,7 +8,7 @@
-
+
diff --git a/src/objects.js b/src/objects.js
index 2b1768d3..2b32a9a7 100644
--- a/src/objects.js
+++ b/src/objects.js
@@ -83,7 +83,7 @@ BlockEditorMorph, BlockDialogMorph, PrototypeHatBlockMorph, localize,
TableMorph, TableFrameMorph, normalizeCanvas, BooleanSlotMorph, HandleMorph,
AlignmentMorph, Process, XML_Element, VectorPaintEditorMorph*/
-modules.objects = '2019-February-07';
+modules.objects = '2019-February-18';
var SpriteMorph;
var StageMorph;
@@ -3206,7 +3206,9 @@ SpriteMorph.prototype.reportSounds = function () {
SpriteMorph.prototype.userMenu = function () {
var ide = this.parentThatIsA(IDE_Morph),
- menu = new MenuMorph(this);
+ menu = new MenuMorph(this),
+ allParts,
+ anchors;
if (ide && ide.isAppMode) {
// menu.addItem('help', 'nop');
@@ -3246,6 +3248,15 @@ SpriteMorph.prototype.userMenu = function () {
localize('detach from') + ' ' + this.anchor.name,
'detachFromAnchor'
);
+ } else {
+ allParts = this.allParts();
+ anchors = this.parent.children.filter(function (morph) {
+ return morph instanceof SpriteMorph &&
+ !contains(allParts, morph);
+ });
+ if (anchors.length) {
+ menu.addMenu('stick to', this.anchorsMenu(anchors));
+ }
}
if (this.parts.length) {
menu.addItem('detach all parts', 'detachAllParts');
@@ -3254,6 +3265,20 @@ SpriteMorph.prototype.userMenu = function () {
return menu;
};
+SpriteMorph.prototype.anchorsMenu = function (targets) {
+ var menu = new MenuMorph(this.attachTo, null, this);
+ targets.forEach(function (sprite) {
+ menu.addItem(
+ [
+ sprite.thumbnail(new Point(24, 24)),
+ sprite.name,
+ ],
+ sprite
+ );
+ });
+ return menu;
+};
+
SpriteMorph.prototype.exportSprite = function () {
if (this.isTemporary) {return; }
var ide = this.parentThatIsA(IDE_Morph);
@@ -5987,6 +6012,10 @@ SpriteMorph.prototype.booleanMorph = function (bool) {
simulate Morphic trees
*/
+SpriteMorph.prototype.attachTo = function (aSprite) {
+ aSprite.attachPart(this);
+};
+
SpriteMorph.prototype.attachPart = function (aSprite) {
var v = Date.now();
if (aSprite.anchor) {