summaryrefslogtreecommitdiff
path: root/blocks.js
diff options
context:
space:
mode:
Diffstat (limited to 'blocks.js')
-rw-r--r--blocks.js164
1 files changed, 129 insertions, 35 deletions
diff --git a/blocks.js b/blocks.js
index 2e297ab..6210e22 100644
--- a/blocks.js
+++ b/blocks.js
@@ -155,7 +155,7 @@ DialogBoxMorph, BlockInputFragmentMorph, PrototypeHatBlockMorph, Costume*/
// Global stuff ////////////////////////////////////////////////////////
-modules.blocks = '2014-July-30';
+modules.blocks = '2014-November-21';
var SyntaxElementMorph;
@@ -394,12 +394,13 @@ SyntaxElementMorph.prototype.allInputs = function () {
};
SyntaxElementMorph.prototype.allEmptySlots = function () {
-/*
- answer empty input slots of all children excluding myself,
- but omit those in nested rings (lambdas)
-*/
+ // answer empty input slots of all children excluding myself,
+ // but omit those in nested rings (lambdas) and JS-Function primitives.
+ // Used by the evaluator when binding implicit formal parameters
+ // to empty input slots
var empty = [];
- if (!(this instanceof RingMorph)) {
+ if (!(this instanceof RingMorph) &&
+ (this.selector !== 'reportJSFunction')) {
this.children.forEach(function (morph) {
if (morph.isEmptySlot && morph.isEmptySlot()) {
empty.push(morph);
@@ -411,6 +412,26 @@ SyntaxElementMorph.prototype.allEmptySlots = function () {
return empty;
};
+SyntaxElementMorph.prototype.tagExitBlocks = function (stopTag, isCommand) {
+ // tag 'report' and 'stop this block' blocks of all children including
+ // myself, with either a stopTag (for "stop" blocks) or an indicator of
+ // being inside a command block definition, but omit those in nested
+ // rings (lambdas. Used by the evaluator when entering a procedure
+ if (this.selector === 'doReport') {
+ this.partOfCustomCommand = isCommand;
+ } else if (this.selector === 'doStopThis') {
+ this.exitTag = stopTag;
+ } else {
+ if (!(this instanceof RingMorph)) {
+ this.children.forEach(function (morph) {
+ if (morph.tagExitBlocks) {
+ morph.tagExitBlocks(stopTag, isCommand);
+ }
+ });
+ }
+ }
+};
+
SyntaxElementMorph.prototype.replaceInput = function (oldArg, newArg) {
var scripts = this.parentThatIsA(ScriptsMorph),
replacement = newArg,
@@ -655,7 +676,9 @@ SyntaxElementMorph.prototype.labelPart = function (spec) {
var part, tokens;
if (spec[0] === '%' &&
spec.length > 1 &&
- this.selector !== 'reportGetVar') {
+ (this.selector !== 'reportGetVar' ||
+ (spec === '%turtleOutline' && this.isObjInputFragment()))) {
+
// check for variable multi-arg-slot:
if ((spec.length > 5) && (spec.slice(0, 5) === '%mult')) {
part = new MultiArgMorph(spec.slice(5));
@@ -843,6 +866,25 @@ SyntaxElementMorph.prototype.labelPart = function (spec) {
);
part.setContents(['date']);
break;
+ case '%locations':
+ part = new InputSlotMorph(
+ null, // text
+ false, // non-numeric
+ {
+ 'all' : ['all'],
+ 'country' : ['country'],
+ 'state' : ['state'],
+ 'state district' : ['state district'],
+ 'suburb' : ['suburb'],
+ 'city' : ['city'],
+ 'road' : ['road'],
+ 'house number' : ['house number'],
+ 'licence': ['licence']
+ },
+ true // read-only
+ );
+ part.setContents(['all']);
+ break;
case '%delim':
part = new InputSlotMorph(
null, // text
@@ -950,6 +992,8 @@ SyntaxElementMorph.prototype.labelPart = function (spec) {
null,
false,
{
+ 'any key': ['any key'],
+ 'number key': ['number key'],
'up arrow': ['up arrow'],
'down arrow': ['down arrow'],
'right arrow': ['right arrow'],
@@ -1360,6 +1404,13 @@ SyntaxElementMorph.prototype.labelPart = function (spec) {
return part;
};
+SyntaxElementMorph.prototype.isObjInputFragment = function () {
+ // private - for displaying a symbol in a variable block template
+ return (this.selector === 'reportGetVar') &&
+ (this.getSlotSpec() === '%t') &&
+ (this.parent.fragment.type === '%obj');
+};
+
// SyntaxElementMorph layout:
SyntaxElementMorph.prototype.fixLayout = function () {
@@ -2147,9 +2198,16 @@ BlockMorph.prototype.userMenu = function () {
this.thumbnail(0.5, 60, false),
function () {
var cpy = this.fullCopy(),
- nb = cpy.nextBlock();
+ nb = cpy.nextBlock(),
+ ide = myself.parentThatIsA(IDE_Morph);
if (nb) {nb.destroy(); }
cpy.pickUp(world);
+ if (ide) {
+ world.hand.grabOrigin = {
+ origin: ide.palette,
+ position: ide.palette.center()
+ };
+ }
},
'only duplicate this block'
);
@@ -3152,9 +3210,14 @@ BlockMorph.prototype.snap = function () {
I inherit from BlockMorph adding the following most important
public accessors:
- nextBlock() - set / get the block attached to my bottom
- bottomBlock() - answer the bottom block of my stack
- blockSequence() - answer an array of blocks starting with myself
+ nextBlock() - set / get the block attached to my bottom
+ bottomBlock() - answer the bottom block of my stack
+ blockSequence() - answer an array of blocks starting with myself
+
+ and the following "lexical awareness" indicators:
+
+ partOfCustomCommand - temporary bool set by the evaluator
+ exitTag - temporary string or number set by the evaluator
*/
// CommandBlockMorph inherits from BlockMorph:
@@ -3172,6 +3235,8 @@ function CommandBlockMorph() {
CommandBlockMorph.prototype.init = function () {
CommandBlockMorph.uber.init.call(this);
this.setExtent(new Point(200, 100));
+ this.partOfCustomCommand = false;
+ this.exitTag = null;
};
// CommandBlockMorph enumerating:
@@ -6754,9 +6819,6 @@ InputSlotMorph.prototype.soundsMenu = function () {
InputSlotMorph.prototype.getVarNamesDict = function () {
var block = this.parentThatIsA(BlockMorph),
rcvr,
- proto,
- rings,
- declarations,
tempVars = [],
dict;
@@ -6764,28 +6826,26 @@ InputSlotMorph.prototype.getVarNamesDict = function () {
return {};
}
rcvr = block.receiver();
-
- proto = detect(block.allParents(), function (morph) {
- return morph instanceof PrototypeHatBlockMorph;
- });
- if (proto) {
- tempVars = proto.inputs()[0].inputFragmentNames();
- }
-
- rings = block.allParents().filter(function (block) {
- return block instanceof RingMorph;
- });
- rings.forEach(function (block) {
- tempVars = tempVars.concat(block.inputs()[1].evaluate());
- });
-
- declarations = block.allParents().filter(function (block) {
- return block.selector === 'doDeclareVariables';
- });
- declarations.forEach(function (block) {
- tempVars = tempVars.concat(block.inputs()[0].evaluate());
+ block.allParents().forEach(function (morph) {
+ if (morph instanceof PrototypeHatBlockMorph) {
+ tempVars.push.apply(
+ tempVars,
+ morph.inputs()[0].inputFragmentNames()
+ );
+ } else if (morph instanceof BlockMorph) {
+ morph.inputs().forEach(function (inp) {
+ if (inp instanceof TemplateSlotMorph) {
+ tempVars.push(inp.contents());
+ } else if (inp instanceof MultiArgMorph) {
+ inp.children.forEach(function (m) {
+ if (m instanceof TemplateSlotMorph) {
+ tempVars.push(m.contents());
+ }
+ });
+ }
+ });
+ }
});
-
if (rcvr) {
dict = rcvr.variables.allNamesDict();
tempVars.forEach(function (name) {
@@ -7714,6 +7774,8 @@ SymbolMorph.prototype.names = [
'pointRight',
'gears',
'file',
+ 'mutedSounds',
+ 'unmutedSounds',
'fullScreen',
'normalScreen',
'smallStage',
@@ -7838,6 +7900,10 @@ SymbolMorph.prototype.symbolCanvasColored = function (aColor) {
return this.drawSymbolGears(canvas, aColor);
case 'file':
return this.drawSymbolFile(canvas, aColor);
+ case 'mutedSounds':
+ return this.drawSymbolMutedSounds(canvas, aColor);
+ case 'unmutedSounds':
+ return this.drawSymbolUnmutedSounds(canvas, aColor);
case 'fullScreen':
return this.drawSymbolFullScreen(canvas, aColor);
case 'normalScreen':
@@ -8040,6 +8106,34 @@ SymbolMorph.prototype.drawSymbolFile = function (canvas, color) {
return canvas;
};
+SymbolMorph.prototype.drawSymbolMutedSounds = function (canvas, color) {
+ // answer a canvas showing a muted sounds toggling symbol
+ var ctx = canvas.getContext('2d'),
+ w = canvas.width,
+ h = canvas.height,
+ w2 = w / 2,
+ h2 = h / 2;
+
+ ctx.fillStyle = color.darker(40).toString();
+ ctx.fillRect(0, 0, w, h);
+
+ return canvas;
+};
+
+SymbolMorph.prototype.drawSymbolUnmutedSounds = function (canvas, color) {
+ // answer a canvas showing a UNmuted sounds toggling symbol
+ var ctx = canvas.getContext('2d'),
+ w = canvas.width,
+ h = canvas.height,
+ w2 = w / 2,
+ h2 = h / 2;
+
+ ctx.fillStyle = color.darker(60).toString();
+ ctx.fillRect(0, 0, w, h);
+
+ return canvas;
+};
+
SymbolMorph.prototype.drawSymbolFullScreen = function (canvas, color) {
// answer a canvas showing two arrows pointing diagonally outwards
var ctx = canvas.getContext('2d'),