summaryrefslogtreecommitdiff
path: root/objects.js
diff options
context:
space:
mode:
Diffstat (limited to 'objects.js')
-rw-r--r--objects.js193
1 files changed, 142 insertions, 51 deletions
diff --git a/objects.js b/objects.js
index 5450a49..50868df 100644
--- a/objects.js
+++ b/objects.js
@@ -125,7 +125,7 @@ PrototypeHatBlockMorph*/
// Global stuff ////////////////////////////////////////////////////////
-modules.objects = '2014-July-30';
+modules.objects = '2014-December-04';
var SpriteMorph;
var StageMorph;
@@ -830,6 +830,11 @@ SpriteMorph.prototype.initBlocks = function () {
category: 'sensing',
spec: 'key %key pressed?'
},
+ getKeysPressed: {
+ type: 'reporter',
+ category: 'sensing',
+ spec: 'keys pressed'
+ },
reportDistanceTo: {
type: 'reporter',
category: 'sensing',
@@ -1161,6 +1166,13 @@ SpriteMorph.prototype.initBlocks = function () {
category: 'lists',
spec: 'map %repRing over %l'
},
+ doForEach: {
+ dev: true,
+ type: 'command',
+ category: 'lists',
+ spec: 'for %upvar in %l %cs',
+ defaults: [localize('each item')]
+ },
// Code mapping - experimental
doMapCodeOrHeader: { // experimental
@@ -1684,6 +1696,20 @@ SpriteMorph.prototype.blockTemplates = function (category) {
return menu;
}
+ function addVar(pair) {
+ if (pair) {
+ if (myself.variables.silentFind(pair[0])) {
+ myself.inform('that name is already in use');
+ } else {
+ myself.addVariable(pair[0], pair[1]);
+ myself.toggleVariableWatcher(pair[0], pair[1]);
+ myself.blocksCache[cat] = null;
+ myself.paletteCache[cat] = null;
+ myself.parentThatIsA(IDE_Morph).refreshPalette();
+ }
+ }
+ }
+
if (cat === 'motion') {
blocks.push(block('forward'));
@@ -1879,6 +1905,7 @@ SpriteMorph.prototype.blockTemplates = function (category) {
blocks.push(block('reportMouseDown'));
blocks.push('-');
blocks.push(block('reportKeyPressed'));
+ blocks.push(block('getKeysPressed'));
blocks.push('-');
blocks.push(block('reportDistanceTo'));
blocks.push('-');
@@ -1980,15 +2007,7 @@ SpriteMorph.prototype.blockTemplates = function (category) {
function () {
new VariableDialogMorph(
null,
- function (pair) {
- if (pair && !myself.variables.silentFind(pair[0])) {
- myself.addVariable(pair[0], pair[1]);
- myself.toggleVariableWatcher(pair[0], pair[1]);
- myself.blocksCache[cat] = null;
- myself.paletteCache[cat] = null;
- myself.parentThatIsA(IDE_Morph).refreshPalette();
- }
- },
+ addVar,
myself
).prompt(
'Variable name',
@@ -2070,6 +2089,8 @@ SpriteMorph.prototype.blockTemplates = function (category) {
blocks.push(txt);
blocks.push('-');
blocks.push(block('reportMap'));
+ blocks.push('-');
+ blocks.push(block('doForEach'));
}
/////////////////////////////////
@@ -2177,8 +2198,8 @@ SpriteMorph.prototype.freshPalette = function (category) {
var defs = SpriteMorph.prototype.blocks,
hiddens = StageMorph.prototype.hiddenPrimitives;
return Object.keys(hiddens).some(function (any) {
- return defs[any].category === category ||
- contains((more[category] || []), any);
+ return !isNil(defs[any]) && (defs[any].category === category
+ || contains((more[category] || []), any));
});
}
@@ -2217,7 +2238,7 @@ SpriteMorph.prototype.freshPalette = function (category) {
var hiddens = StageMorph.prototype.hiddenPrimitives,
defs = SpriteMorph.prototype.blocks;
Object.keys(hiddens).forEach(function (sel) {
- if (defs[sel].category === category) {
+ if (defs[sel] && (defs[sel].category === category)) {
delete StageMorph.prototype.hiddenPrimitives[sel];
}
});
@@ -3245,8 +3266,11 @@ SpriteMorph.prototype.setCenter = function (aPoint, justMe) {
SpriteMorph.prototype.nestingBounds = function () {
// same as fullBounds(), except that it uses "parts" instead of children
- var result;
- result = this.bounds;
+ // and special cases the costume-less "arrow" shape's bounding box
+ var result = this.bounds;
+ if (!this.costume && this.penBounds) {
+ result = this.penBounds.translateBy(this.position());
+ }
this.parts.forEach(function (part) {
if (part.isVisible) {
result = result.merge(part.nestingBounds());
@@ -3261,9 +3285,7 @@ Morph.prototype.setPosition = function (aPoint, justMe) {
// override the inherited default to make sure my parts follow
// unless it's justMe
var delta = aPoint.subtract(this.topLeft());
- if ((delta.x !== 0) || (delta.y !== 0)) {
- this.moveBy(delta, justMe);
- }
+ this.moveBy(delta, justMe);
};
SpriteMorph.prototype.forward = function (steps) {
@@ -3470,6 +3492,7 @@ SpriteMorph.prototype.allMessageNames = function () {
};
SpriteMorph.prototype.allHatBlocksFor = function (message) {
+ if (typeof message === 'number') {message = message.toString(); }
return this.scripts.children.filter(function (morph) {
var event;
if (morph.selector) {
@@ -3495,7 +3518,19 @@ SpriteMorph.prototype.allHatBlocksForKey = function (key) {
return this.scripts.children.filter(function (morph) {
if (morph.selector) {
if (morph.selector === 'receiveKey') {
- return morph.inputs()[0].evaluate()[0] === key;
+ var selectedOption = morph.inputs()[0].evaluate()[0];
+
+ if (selectedOption === 'any key') {
+ return true;
+ }
+ if (selectedOption === 'number key' &&
+ (key >= '0' && key <= '9')) {
+ return true;
+ }
+ if (selectedOption === key) {
+ return true;
+ }
+ return false;
}
}
return false;
@@ -3539,6 +3574,16 @@ SpriteMorph.prototype.getTempo = function () {
return 0;
};
+// SpriteMorph last key
+
+SpriteMorph.prototype.getKeysPressed = function () {
+ var stage = this.parentThatIsA(StageMorph);
+ if (stage) {
+ return stage.getKeysPressed();
+ }
+ return '';
+};
+
// SpriteMorph last message
SpriteMorph.prototype.getLastMessage = function () {
@@ -4394,17 +4439,33 @@ StageMorph.prototype.drawOn = function (aCanvas, aRect) {
hs = h / this.scale;
context.save();
context.scale(this.scale, this.scale);
- context.drawImage(
- this.penTrails(),
- src.left() / this.scale,
- src.top() / this.scale,
- ws,
- hs,
- area.left() / this.scale,
- area.top() / this.scale,
- ws,
- hs
- );
+ try {
+ context.drawImage(
+ this.penTrails(),
+ src.left() / this.scale,
+ src.top() / this.scale,
+ ws,
+ hs,
+ area.left() / this.scale,
+ area.top() / this.scale,
+ ws,
+ hs
+ );
+ } catch (err) { // sometimes triggered only by Firefox
+ // console.log(err);
+ context.restore();
+ context.drawImage(
+ this.penTrails(),
+ 0,
+ 0,
+ this.dimensions.x,
+ this.dimensions.y,
+ this.left(),
+ this.top(),
+ this.dimensions.x * this.scale,
+ this.dimensions.y * this.scale
+ );
+ }
context.restore();
}
};
@@ -4523,6 +4584,16 @@ StageMorph.prototype.getTempo = function () {
return +this.tempo;
};
+// StageMorph keys
+
+StageMorph.prototype.getKeysPressed = function () {
+ var keys = [];
+ for (var key in this.keysPressed) {
+ keys.push(key);
+ }
+ return new List(keys);
+};
+
// StageMorph messages
StageMorph.prototype.getLastMessage = function () {
@@ -4576,7 +4647,7 @@ StageMorph.prototype.step = function () {
world.keyboardReceiver = this;
}
if (world.currentKey === null) {
- this.keyPressed = null;
+ this.keysPressed = {};
}
// manage threads
@@ -4687,6 +4758,7 @@ StageMorph.prototype.fireKeyEvent = function (key) {
var evt = key.toLowerCase(),
hats = [],
procs = [],
+ ide = this.parentThatIsA(IDE_Morph),
myself = this;
this.keysPressed[evt] = true;
@@ -4694,19 +4766,24 @@ StageMorph.prototype.fireKeyEvent = function (key) {
return this.fireGreenFlagEvent();
}
if (evt === 'ctrl f') {
- return this.parentThatIsA(IDE_Morph).currentSprite.searchBlocks();
+ if (!ide.isAppMode) {ide.currentSprite.searchBlocks(); }
+ return;
}
if (evt === 'ctrl n') {
- return this.parentThatIsA(IDE_Morph).createNewProject();
+ if (!ide.isAppMode) {ide.createNewProject(); }
+ return;
}
if (evt === 'ctrl o') {
- return this.parentThatIsA(IDE_Morph).openProjectsBrowser();
+ if (!ide.isAppMode) {ide.openProjectsBrowser(); }
+ return;
}
if (evt === 'ctrl s') {
- return this.parentThatIsA(IDE_Morph).save();
+ if (!ide.isAppMode) {ide.save(); }
+ return;
}
if (evt === 'ctrl shift s') {
- return this.parentThatIsA(IDE_Morph).saveProjectsBrowser();
+ if (!ide.isAppMode) {return ide.saveProjectsBrowser(); }
+ return;
}
if (evt === 'esc') {
return this.fireStopAllEvent();
@@ -4848,6 +4925,20 @@ StageMorph.prototype.blockTemplates = function (category) {
);
}
+ function addVar(pair) {
+ if (pair) {
+ if (myself.variables.silentFind(pair[0])) {
+ myself.inform('that name is already in use');
+ } else {
+ myself.addVariable(pair[0], pair[1]);
+ myself.toggleVariableWatcher(pair[0], pair[1]);
+ myself.blocksCache[cat] = null;
+ myself.paletteCache[cat] = null;
+ myself.parentThatIsA(IDE_Morph).refreshPalette();
+ }
+ }
+ }
+
if (cat === 'motion') {
txt = new TextMorph(localize(
@@ -4991,6 +5082,7 @@ StageMorph.prototype.blockTemplates = function (category) {
blocks.push(block('reportMouseDown'));
blocks.push('-');
blocks.push(block('reportKeyPressed'));
+ blocks.push(block('getKeysPressed'));
blocks.push('-');
blocks.push(block('doResetTimer'));
blocks.push(watcherToggle('getTimer'));
@@ -5092,15 +5184,7 @@ StageMorph.prototype.blockTemplates = function (category) {
function () {
new VariableDialogMorph(
null,
- function (pair) {
- if (pair && !myself.variables.silentFind(pair[0])) {
- myself.addVariable(pair[0], pair[1]);
- myself.toggleVariableWatcher(pair[0], pair[1]);
- myself.blocksCache[cat] = null;
- myself.paletteCache[cat] = null;
- myself.parentThatIsA(IDE_Morph).refreshPalette();
- }
- },
+ addVar,
myself
).prompt(
'Variable name',
@@ -5176,6 +5260,8 @@ StageMorph.prototype.blockTemplates = function (category) {
blocks.push(txt);
blocks.push('-');
blocks.push(block('reportMap'));
+ blocks.push('-');
+ blocks.push(block('doForEach'));
}
/////////////////////////////////
@@ -5314,7 +5400,7 @@ StageMorph.prototype.thumbnail = function (extentPoint, excludedSprite) {
this.dimensions.y * this.scale
);
this.children.forEach(function (morph) {
- if (morph !== excludedSprite) {
+ if (morph.isVisible && (morph !== excludedSprite)) {
fb = morph.fullBounds();
fimg = morph.fullImage();
if (fimg.width && fimg.height) {
@@ -6423,10 +6509,14 @@ CellMorph.prototype.drawNew = function () {
}
this.contentsMorph.setColor(new Color(255, 255, 255));
} else if (typeof this.contents === 'boolean') {
- this.contentsMorph = SpriteMorph.prototype.booleanMorph.call(
+ img = SpriteMorph.prototype.booleanMorph.call(
null,
this.contents
- );
+ ).fullImage();
+ this.contentsMorph = new Morph();
+ this.contentsMorph.silentSetWidth(img.width);
+ this.contentsMorph.silentSetHeight(img.height);
+ this.contentsMorph.image = img;
} else if (this.contents instanceof HTMLCanvasElement) {
this.contentsMorph = new Morph();
this.contentsMorph.silentSetWidth(this.contents.width);
@@ -6719,7 +6809,7 @@ WatcherMorph.prototype.object = function () {
WatcherMorph.prototype.isGlobal = function (selector) {
return contains(
- ['getLastAnswer', 'getLastMessage', 'getTempo', 'getTimer',
+ ['getLastAnswer', 'getKeysPressed', 'getLastMessage', 'getTempo', 'getTimer',
'reportMouseX', 'reportMouseY'],
selector
);
@@ -6751,7 +6841,8 @@ WatcherMorph.prototype.update = function () {
if (this.target && this.getter) {
this.updateLabel();
if (this.target instanceof VariableFrame) {
- newValue = this.target.vars[this.getter];
+ newValue = this.target.vars[this.getter] ?
+ this.target.vars[this.getter].value : undefined;
} else {
newValue = this.target[this.getter]();
}
@@ -6836,7 +6927,7 @@ WatcherMorph.prototype.fixLayout = function () {
this.sliderMorph.button.pressColor.b += 100;
this.sliderMorph.setHeight(fontSize);
this.sliderMorph.action = function (num) {
- myself.target.vars[myself.getter] = Math.round(num);
+ myself.target.vars[myself.getter].value = Math.round(num);
};
this.add(this.sliderMorph);
}