kopia lustrzana https://github.com/backface/turtlestitch
Codification (blocks to text) support complete
text code mapping and block header support, both via GUI and primitives, for built-in blocks and for custom ones.pull/3/merge
rodzic
8e0f60fdd6
commit
b59f7f3e27
165
blocks.js
165
blocks.js
|
@ -155,7 +155,7 @@ DialogBoxMorph, BlockInputFragmentMorph, PrototypeHatBlockMorph*/
|
||||||
|
|
||||||
// Global stuff ////////////////////////////////////////////////////////
|
// Global stuff ////////////////////////////////////////////////////////
|
||||||
|
|
||||||
modules.blocks = '2013-June-25';
|
modules.blocks = '2013-July-04';
|
||||||
|
|
||||||
var SyntaxElementMorph;
|
var SyntaxElementMorph;
|
||||||
var BlockMorph;
|
var BlockMorph;
|
||||||
|
@ -1535,10 +1535,10 @@ SyntaxElementMorph.prototype.showBubble = function (value) {
|
||||||
it's not part of Snap's evaluator and not needed for Snap itself
|
it's not part of Snap's evaluator and not needed for Snap itself
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SyntaxElementMorph.prototype.mappedCode = function () {
|
SyntaxElementMorph.prototype.mappedCode = function (definitions) {
|
||||||
var result = this.evaluate();
|
var result = this.evaluate();
|
||||||
if (result instanceof BlockMorph) {
|
if (result instanceof BlockMorph) {
|
||||||
return result.mappedCode();
|
return result.mappedCode(definitions);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
@ -1858,6 +1858,10 @@ BlockMorph.prototype.userMenu = function () {
|
||||||
}
|
}
|
||||||
if (StageMorph.prototype.enableCodeMapping) {
|
if (StageMorph.prototype.enableCodeMapping) {
|
||||||
menu.addLine();
|
menu.addLine();
|
||||||
|
menu.addItem(
|
||||||
|
'header mapping...',
|
||||||
|
'mapToHeader'
|
||||||
|
);
|
||||||
menu.addItem(
|
menu.addItem(
|
||||||
'code mapping...',
|
'code mapping...',
|
||||||
'mapToCode'
|
'mapToCode'
|
||||||
|
@ -1941,6 +1945,11 @@ BlockMorph.prototype.userMenu = function () {
|
||||||
menu.addLine();
|
menu.addLine();
|
||||||
menu.addItem("ringify", 'ringify');
|
menu.addItem("ringify", 'ringify');
|
||||||
if (StageMorph.prototype.enableCodeMapping) {
|
if (StageMorph.prototype.enableCodeMapping) {
|
||||||
|
menu.addLine();
|
||||||
|
menu.addItem(
|
||||||
|
'header mapping...',
|
||||||
|
'mapToHeader'
|
||||||
|
);
|
||||||
menu.addItem(
|
menu.addItem(
|
||||||
'code mapping...',
|
'code mapping...',
|
||||||
'mapToCode'
|
'mapToCode'
|
||||||
|
@ -2182,6 +2191,45 @@ BlockMorph.prototype.showHelp = function () {
|
||||||
it's not part of Snap's evaluator and not needed for Snap itself
|
it's not part of Snap's evaluator and not needed for Snap itself
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
BlockMorph.prototype.mapToHeader = function () {
|
||||||
|
// open a dialog box letting the user map header code via the GUI
|
||||||
|
var key = this.selector.substr(0, 5) === 'reify' ?
|
||||||
|
'reify' : this.selector,
|
||||||
|
block = this.codeDefinitionHeader(),
|
||||||
|
myself = this,
|
||||||
|
help,
|
||||||
|
pic;
|
||||||
|
block.addShadow(new Point(3, 3));
|
||||||
|
pic = block.fullImageClassic();
|
||||||
|
if (this.definition) {
|
||||||
|
help = 'Enter code that corresponds to the block\'s definition. ' +
|
||||||
|
'Use the formal parameter\nnames as shown and <body> to ' +
|
||||||
|
'reference the definition body\'s generated text code.';
|
||||||
|
} else {
|
||||||
|
help = 'Enter code that corresponds to the block\'s definition. ' +
|
||||||
|
'Choose your own\nformal parameter names (ignoring the ones ' +
|
||||||
|
'shown .';
|
||||||
|
}
|
||||||
|
new DialogBoxMorph(
|
||||||
|
this,
|
||||||
|
function (code) {
|
||||||
|
if (key === 'evaluateCustomBlock') {
|
||||||
|
myself.definition.codeHeader = code;
|
||||||
|
} else {
|
||||||
|
StageMorph.prototype.codeHeaders[key] = code;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
this
|
||||||
|
).promptCode(
|
||||||
|
'Header mapping',
|
||||||
|
key === 'evaluateCustomBlock' ? this.definition.codeHeader || ''
|
||||||
|
: StageMorph.prototype.codeHeaders[key] || '',
|
||||||
|
this.world(),
|
||||||
|
pic,
|
||||||
|
help
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
BlockMorph.prototype.mapToCode = function () {
|
BlockMorph.prototype.mapToCode = function () {
|
||||||
// open a dialog box letting the user map code via the GUI
|
// open a dialog box letting the user map code via the GUI
|
||||||
var key = this.selector.substr(0, 5) === 'reify' ?
|
var key = this.selector.substr(0, 5) === 'reify' ?
|
||||||
|
@ -2206,10 +2254,26 @@ BlockMorph.prototype.mapToCode = function () {
|
||||||
key === 'evaluateCustomBlock' ? this.definition.codeMapping || ''
|
key === 'evaluateCustomBlock' ? this.definition.codeMapping || ''
|
||||||
: StageMorph.prototype.codeMappings[key] || '',
|
: StageMorph.prototype.codeMappings[key] || '',
|
||||||
this.world(),
|
this.world(),
|
||||||
pic
|
pic,
|
||||||
|
'Enter code that corresponds to the block\'s operation ' +
|
||||||
|
'(usually a single\nfunction invocation). Use <#n> to ' +
|
||||||
|
'reference actual arguments as shown.'
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
BlockMorph.prototype.mapHeader = function (aString, key) {
|
||||||
|
// primitive for programatically mapping header code
|
||||||
|
var sel = key || this.selector.substr(0, 5) === 'reify' ?
|
||||||
|
'reify' : this.selector;
|
||||||
|
if (aString) {
|
||||||
|
if (this.definition) { // custom block
|
||||||
|
this.definition.codeHeader = aString;
|
||||||
|
} else {
|
||||||
|
StageMorph.prototype.codeHeaders[sel] = aString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
BlockMorph.prototype.mapCode = function (aString, key) {
|
BlockMorph.prototype.mapCode = function (aString, key) {
|
||||||
// primitive for programatically mapping code
|
// primitive for programatically mapping code
|
||||||
var sel = key || this.selector.substr(0, 5) === 'reify' ?
|
var sel = key || this.selector.substr(0, 5) === 'reify' ?
|
||||||
|
@ -2223,19 +2287,63 @@ BlockMorph.prototype.mapCode = function (aString, key) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
BlockMorph.prototype.mappedCode = function () {
|
BlockMorph.prototype.mappedCode = function (definitions) {
|
||||||
var key = this.selector.substr(0, 5) === 'reify' ?
|
var key = this.selector.substr(0, 5) === 'reify' ?
|
||||||
'reify' : this.selector,
|
'reify' : this.selector,
|
||||||
code,
|
code,
|
||||||
codeLines,
|
codeLines,
|
||||||
count = 1,
|
count = 1,
|
||||||
|
header,
|
||||||
|
headers,
|
||||||
|
headerLines,
|
||||||
|
body,
|
||||||
|
bodyLines,
|
||||||
|
defKey = this.definition ? this.definition.spec : key,
|
||||||
|
defs = definitions || {},
|
||||||
parts = [];
|
parts = [];
|
||||||
code = key === 'reportGetVar' ? this.blockSpec
|
code = key === 'reportGetVar' ? this.blockSpec
|
||||||
: this.definition ? this.definition.codeMapping || ''
|
: this.definition ? this.definition.codeMapping || ''
|
||||||
: StageMorph.prototype.codeMappings[key] || '';
|
: StageMorph.prototype.codeMappings[key] || '';
|
||||||
|
|
||||||
|
// map header
|
||||||
|
if (key !== 'reportGetVar' && !defs.hasOwnProperty(defKey)) {
|
||||||
|
defs[defKey] = null; // create the property for recursive definitions
|
||||||
|
if (this.definition) {
|
||||||
|
header = this.definition.codeHeader || '';
|
||||||
|
if (header.indexOf('<body') !== -1) { // replace with def mapping
|
||||||
|
body = '';
|
||||||
|
if (this.definition.body) {
|
||||||
|
body = this.definition.body.expression.mappedCode(defs);
|
||||||
|
}
|
||||||
|
bodyLines = body.split('\n');
|
||||||
|
headerLines = header.split('\n');
|
||||||
|
headerLines.forEach(function (headerLine, idx) {
|
||||||
|
var prefix = '',
|
||||||
|
indent;
|
||||||
|
if (headerLine.trimLeft().indexOf('<body') === 0) {
|
||||||
|
indent = headerLine.indexOf('<body');
|
||||||
|
prefix = headerLine.slice(0, indent);
|
||||||
|
}
|
||||||
|
headerLines[idx] = headerLine.replace(
|
||||||
|
new RegExp('<body>'),
|
||||||
|
bodyLines.join('\n' + prefix)
|
||||||
|
);
|
||||||
|
headerLines[idx] = headerLines[idx].replace(
|
||||||
|
new RegExp('<body>', 'g'),
|
||||||
|
bodyLines.join('\n')
|
||||||
|
);
|
||||||
|
});
|
||||||
|
header = headerLines.join('\n');
|
||||||
|
}
|
||||||
|
defs[defKey] = header;
|
||||||
|
} else {
|
||||||
|
defs[defKey] = StageMorph.prototype.codeHeaders[defKey];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
codeLines = code.split('\n');
|
codeLines = code.split('\n');
|
||||||
this.inputs().forEach(function (input) {
|
this.inputs().forEach(function (input) {
|
||||||
parts.push(input.mappedCode().toString());
|
parts.push(input.mappedCode(defs).toString());
|
||||||
});
|
});
|
||||||
parts.forEach(function (part) {
|
parts.forEach(function (part) {
|
||||||
var partLines = part.split('\n'),
|
var partLines = part.split('\n'),
|
||||||
|
@ -2258,11 +2366,46 @@ BlockMorph.prototype.mappedCode = function () {
|
||||||
});
|
});
|
||||||
code = codeLines.join('\n');
|
code = codeLines.join('\n');
|
||||||
if (this.nextBlock && this.nextBlock()) { // Command
|
if (this.nextBlock && this.nextBlock()) { // Command
|
||||||
code += ('\n' + this.nextBlock().mappedCode());
|
code += ('\n' + this.nextBlock().mappedCode(defs));
|
||||||
|
}
|
||||||
|
if (!definitions) { // top-level, add headers
|
||||||
|
headers = [];
|
||||||
|
Object.keys(defs).forEach(function (each) {
|
||||||
|
if (defs[each]) {
|
||||||
|
headers.push(defs[each]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (headers.length) {
|
||||||
|
return headers.join('\n\n')
|
||||||
|
+ '\n\n'
|
||||||
|
+ code;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return code;
|
return code;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
BlockMorph.prototype.codeDefinitionHeader = function () {
|
||||||
|
var block = this.definition ? new PrototypeHatBlockMorph(this.definition)
|
||||||
|
: SpriteMorph.prototype.blockForSelector(this.selector),
|
||||||
|
hat = new HatBlockMorph(),
|
||||||
|
count = 1;
|
||||||
|
|
||||||
|
if (this.definition) {return block; }
|
||||||
|
block.inputs().forEach(function (input) {
|
||||||
|
var part = new TemplateSlotMorph('#' + count);
|
||||||
|
block.silentReplaceInput(input, part);
|
||||||
|
count += 1;
|
||||||
|
});
|
||||||
|
block.isPrototype = true;
|
||||||
|
hat.setCategory("control");
|
||||||
|
hat.setSpec('%s');
|
||||||
|
hat.silentReplaceInput(hat.inputs()[0], block);
|
||||||
|
if (this.category === 'control') {
|
||||||
|
hat.alternateBlockColor();
|
||||||
|
}
|
||||||
|
return hat;
|
||||||
|
};
|
||||||
|
|
||||||
BlockMorph.prototype.codeMappingHeader = function () {
|
BlockMorph.prototype.codeMappingHeader = function () {
|
||||||
var block = this.definition ? this.definition.blockInstance()
|
var block = this.definition ? this.definition.blockInstance()
|
||||||
: SpriteMorph.prototype.blockForSelector(this.selector),
|
: SpriteMorph.prototype.blockForSelector(this.selector),
|
||||||
|
@ -5402,11 +5545,11 @@ CSlotMorph.prototype.getSpec = function () {
|
||||||
return '%c';
|
return '%c';
|
||||||
};
|
};
|
||||||
|
|
||||||
CSlotMorph.prototype.mappedCode = function () {
|
CSlotMorph.prototype.mappedCode = function (definitions) {
|
||||||
var code = StageMorph.prototype.codeMappings.reify || '<#1>',
|
var code = StageMorph.prototype.codeMappings.reify || '<#1>',
|
||||||
codeLines = code.split('\n'),
|
codeLines = code.split('\n'),
|
||||||
nested = this.nestedBlock(),
|
nested = this.nestedBlock(),
|
||||||
part = nested ? nested.mappedCode() : '',
|
part = nested ? nested.mappedCode(definitions) : '',
|
||||||
partLines = (part.toString()).split('\n'),
|
partLines = (part.toString()).split('\n'),
|
||||||
rx = new RegExp('<#1>', 'g');
|
rx = new RegExp('<#1>', 'g');
|
||||||
|
|
||||||
|
@ -8541,7 +8684,7 @@ MultiArgMorph.prototype.mapToCode = function (key, label) {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
MultiArgMorph.prototype.mappedCode = function () {
|
MultiArgMorph.prototype.mappedCode = function (definitions) {
|
||||||
var block = this.parentThatIsA(BlockMorph),
|
var block = this.parentThatIsA(BlockMorph),
|
||||||
key = '',
|
key = '',
|
||||||
code,
|
code,
|
||||||
|
@ -8564,7 +8707,7 @@ MultiArgMorph.prototype.mappedCode = function () {
|
||||||
delim = StageMorph.prototype.codeMappings[key + 'delim'] || ' ';
|
delim = StageMorph.prototype.codeMappings[key + 'delim'] || ' ';
|
||||||
|
|
||||||
this.inputs().forEach(function (input) {
|
this.inputs().forEach(function (input) {
|
||||||
parts.push(itemCode.replace(/<#1>/g, input.mappedCode()));
|
parts.push(itemCode.replace(/<#1>/g, input.mappedCode(definitions)));
|
||||||
});
|
});
|
||||||
parts.forEach(function (part) {
|
parts.forEach(function (part) {
|
||||||
if (count) {
|
if (count) {
|
||||||
|
|
3
byob.js
3
byob.js
|
@ -105,7 +105,7 @@ CommentMorph, localize, CSlotMorph, SpeechBubbleMorph, MorphicPreferences*/
|
||||||
|
|
||||||
// Global stuff ////////////////////////////////////////////////////////
|
// Global stuff ////////////////////////////////////////////////////////
|
||||||
|
|
||||||
modules.byob = '2013-June-18';
|
modules.byob = '2013-July-04';
|
||||||
|
|
||||||
// Declarations
|
// Declarations
|
||||||
|
|
||||||
|
@ -139,6 +139,7 @@ function CustomBlockDefinition(spec, receiver) {
|
||||||
this.declarations = {}; // {'inputName' : [type, default]}
|
this.declarations = {}; // {'inputName' : [type, default]}
|
||||||
this.comment = null;
|
this.comment = null;
|
||||||
this.codeMapping = null; // experimental, generate text code
|
this.codeMapping = null; // experimental, generate text code
|
||||||
|
this.codeHeader = null; // experimental, generate text code
|
||||||
|
|
||||||
// don't serialize (not needed for functionality):
|
// don't serialize (not needed for functionality):
|
||||||
this.receiver = receiver || null; // for serialization only (pointer)
|
this.receiver = receiver || null; // for serialization only (pointer)
|
||||||
|
|
58
gui.js
58
gui.js
|
@ -68,7 +68,7 @@ sb, CommentMorph, CommandBlockMorph*/
|
||||||
|
|
||||||
// Global stuff ////////////////////////////////////////////////////////
|
// Global stuff ////////////////////////////////////////////////////////
|
||||||
|
|
||||||
modules.gui = '2013-July-02';
|
modules.gui = '2013-July-04';
|
||||||
|
|
||||||
// Declarations
|
// Declarations
|
||||||
|
|
||||||
|
@ -1681,8 +1681,7 @@ IDE_Morph.prototype.applySavedSettings = function () {
|
||||||
zoom = this.getSetting('zoom'),
|
zoom = this.getSetting('zoom'),
|
||||||
language = this.getSetting('language'),
|
language = this.getSetting('language'),
|
||||||
click = this.getSetting('click'),
|
click = this.getSetting('click'),
|
||||||
longform = this.getSetting('longform'),
|
longform = this.getSetting('longform');
|
||||||
code = this.getSetting('code');
|
|
||||||
|
|
||||||
// design
|
// design
|
||||||
if (design === 'flat') {
|
if (design === 'flat') {
|
||||||
|
@ -1714,11 +1713,6 @@ IDE_Morph.prototype.applySavedSettings = function () {
|
||||||
if (longform) {
|
if (longform) {
|
||||||
InputSlotDialogMorph.prototype.isLaunchingExpanded = true;
|
InputSlotDialogMorph.prototype.isLaunchingExpanded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// code mapping
|
|
||||||
if (code && !StageMorph.prototype.enableCodeMapping) {
|
|
||||||
StageMorph.prototype.enableCodeMapping = true;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
IDE_Morph.prototype.saveSetting = function (key, value) {
|
IDE_Morph.prototype.saveSetting = function (key, value) {
|
||||||
|
@ -1763,7 +1757,7 @@ IDE_Morph.prototype.addNewSprite = function () {
|
||||||
this.selectSprite(sprite);
|
this.selectSprite(sprite);
|
||||||
};
|
};
|
||||||
|
|
||||||
IDE_Morph.prototype.paintNewSprite = function() {
|
IDE_Morph.prototype.paintNewSprite = function () {
|
||||||
var sprite = new SpriteMorph(this.globalVariables),
|
var sprite = new SpriteMorph(this.globalVariables),
|
||||||
cos = new Costume(),
|
cos = new Costume(),
|
||||||
myself = this;
|
myself = this;
|
||||||
|
@ -1779,7 +1773,7 @@ IDE_Morph.prototype.paintNewSprite = function() {
|
||||||
this.world(),
|
this.world(),
|
||||||
this,
|
this,
|
||||||
true,
|
true,
|
||||||
function() {myself.removeSprite(sprite); },
|
function () {myself.removeSprite(sprite); },
|
||||||
function () {
|
function () {
|
||||||
sprite.addCostume(cos);
|
sprite.addCostume(cos);
|
||||||
sprite.wearCostume(cos);
|
sprite.wearCostume(cos);
|
||||||
|
@ -2158,26 +2152,7 @@ IDE_Morph.prototype.settingsMenu = function () {
|
||||||
'check for alternative\nGUI design',
|
'check for alternative\nGUI design',
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
addPreference(
|
menu.addLine(); // everything below this line is stored in the project
|
||||||
'Code mapping',
|
|
||||||
function () {
|
|
||||||
StageMorph.prototype.enableCodeMapping =
|
|
||||||
!StageMorph.prototype.enableCodeMapping;
|
|
||||||
if (StageMorph.prototype.enableCodeMapping) {
|
|
||||||
myself.saveSetting('code', true);
|
|
||||||
} else {
|
|
||||||
myself.removeSetting('code');
|
|
||||||
}
|
|
||||||
myself.currentSprite.blocksCache.variables = null;
|
|
||||||
myself.currentSprite.paletteCache.variables = null;
|
|
||||||
myself.refreshPalette();
|
|
||||||
},
|
|
||||||
StageMorph.prototype.enableCodeMapping,
|
|
||||||
'uncheck to disable\nblock to text mapping features',
|
|
||||||
'check for block\nto text mapping features',
|
|
||||||
false
|
|
||||||
);
|
|
||||||
menu.addLine(); // everything below this line is made persistent
|
|
||||||
addPreference(
|
addPreference(
|
||||||
'Thread safe scripts',
|
'Thread safe scripts',
|
||||||
function () {stage.isThreadSafe = !stage.isThreadSafe; },
|
function () {stage.isThreadSafe = !stage.isThreadSafe; },
|
||||||
|
@ -2192,6 +2167,20 @@ IDE_Morph.prototype.settingsMenu = function () {
|
||||||
'uncheck for greater speed\nat variable frame rates',
|
'uncheck for greater speed\nat variable frame rates',
|
||||||
'check for smooth, predictable\nanimations across computers'
|
'check for smooth, predictable\nanimations across computers'
|
||||||
);
|
);
|
||||||
|
addPreference(
|
||||||
|
'Codification support',
|
||||||
|
function () {
|
||||||
|
StageMorph.prototype.enableCodeMapping =
|
||||||
|
!StageMorph.prototype.enableCodeMapping;
|
||||||
|
myself.currentSprite.blocksCache.variables = null;
|
||||||
|
myself.currentSprite.paletteCache.variables = null;
|
||||||
|
myself.refreshPalette();
|
||||||
|
},
|
||||||
|
StageMorph.prototype.enableCodeMapping,
|
||||||
|
'uncheck to disable\nblock to text mapping features',
|
||||||
|
'check for block\nto text mapping features',
|
||||||
|
false
|
||||||
|
);
|
||||||
menu.popup(world, pos);
|
menu.popup(world, pos);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2580,6 +2569,9 @@ IDE_Morph.prototype.newProject = function () {
|
||||||
this.currentSprite = new SpriteMorph(this.globalVariables);
|
this.currentSprite = new SpriteMorph(this.globalVariables);
|
||||||
this.sprites = new List([this.currentSprite]);
|
this.sprites = new List([this.currentSprite]);
|
||||||
StageMorph.prototype.hiddenPrimitives = {};
|
StageMorph.prototype.hiddenPrimitives = {};
|
||||||
|
StageMorph.prototype.codeMappings = {};
|
||||||
|
StageMorph.prototype.codeHeaders = {};
|
||||||
|
StageMorph.prototype.enableCodeMapping = false;
|
||||||
this.setProjectName('');
|
this.setProjectName('');
|
||||||
this.projectNotes = '';
|
this.projectNotes = '';
|
||||||
this.createStage();
|
this.createStage();
|
||||||
|
@ -5115,7 +5107,7 @@ CostumeIconMorph.prototype.renameCostume = function () {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
CostumeIconMorph.prototype.duplicateCostume = function() {
|
CostumeIconMorph.prototype.duplicateCostume = function () {
|
||||||
var wardrobe = this.parentThatIsA(WardrobeMorph),
|
var wardrobe = this.parentThatIsA(WardrobeMorph),
|
||||||
ide = this.parentThatIsA(IDE_Morph),
|
ide = this.parentThatIsA(IDE_Morph),
|
||||||
newcos = this.object.copy(),
|
newcos = this.object.copy(),
|
||||||
|
@ -5494,11 +5486,11 @@ WardrobeMorph.prototype.removeCostumeAt = function (idx) {
|
||||||
this.updateList();
|
this.updateList();
|
||||||
};
|
};
|
||||||
|
|
||||||
WardrobeMorph.prototype.paintNew = function() {
|
WardrobeMorph.prototype.paintNew = function () {
|
||||||
var cos = new Costume(newCanvas(), "Untitled"),
|
var cos = new Costume(newCanvas(), "Untitled"),
|
||||||
ide = this.parentThatIsA(IDE_Morph),
|
ide = this.parentThatIsA(IDE_Morph),
|
||||||
myself = this;
|
myself = this;
|
||||||
cos.edit(this.world(), ide, true, null, function() {
|
cos.edit(this.world(), ide, true, null, function () {
|
||||||
myself.sprite.addCostume(cos);
|
myself.sprite.addCostume(cos);
|
||||||
myself.updateList();
|
myself.updateList();
|
||||||
if (ide) {
|
if (ide) {
|
||||||
|
|
|
@ -1778,3 +1778,7 @@ ______
|
||||||
------
|
------
|
||||||
* Objects: took out "security margin" in Costume's shrinkWrap() method b/c Chrome no longer needs it -> fixed empty costume bug when drawing over the paint editor's bounds
|
* Objects: took out "security margin" in Costume's shrinkWrap() method b/c Chrome no longer needs it -> fixed empty costume bug when drawing over the paint editor's bounds
|
||||||
* GUI: Import libraries feature (in the project menu)
|
* GUI: Import libraries feature (in the project menu)
|
||||||
|
|
||||||
|
130704
|
||||||
|
------
|
||||||
|
* Codification (text code mapping and block header support)
|
||||||
|
|
10
objects.js
10
objects.js
|
@ -123,7 +123,7 @@ PrototypeHatBlockMorph*/
|
||||||
|
|
||||||
// Global stuff ////////////////////////////////////////////////////////
|
// Global stuff ////////////////////////////////////////////////////////
|
||||||
|
|
||||||
modules.objects = '2013-July-02';
|
modules.objects = '2013-July-04';
|
||||||
|
|
||||||
var SpriteMorph;
|
var SpriteMorph;
|
||||||
var StageMorph;
|
var StageMorph;
|
||||||
|
@ -1019,6 +1019,11 @@ SpriteMorph.prototype.initBlocks = function () {
|
||||||
},
|
},
|
||||||
|
|
||||||
// Code mapping - experimental
|
// Code mapping - experimental
|
||||||
|
doMapHeader: { // experimental
|
||||||
|
type: 'command',
|
||||||
|
category: 'other',
|
||||||
|
spec: 'map %cmdRing to header %code'
|
||||||
|
},
|
||||||
doMapCode: { // experimental
|
doMapCode: { // experimental
|
||||||
type: 'command',
|
type: 'command',
|
||||||
category: 'other',
|
category: 'other',
|
||||||
|
@ -1795,6 +1800,7 @@ SpriteMorph.prototype.blockTemplates = function (category) {
|
||||||
blocks.push('=');
|
blocks.push('=');
|
||||||
|
|
||||||
if (StageMorph.prototype.enableCodeMapping) {
|
if (StageMorph.prototype.enableCodeMapping) {
|
||||||
|
blocks.push(block('doMapHeader'));
|
||||||
blocks.push(block('doMapCode'));
|
blocks.push(block('doMapCode'));
|
||||||
blocks.push(block('doMapStringCode'));
|
blocks.push(block('doMapStringCode'));
|
||||||
blocks.push(block('doMapListCode'));
|
blocks.push(block('doMapListCode'));
|
||||||
|
@ -3223,6 +3229,7 @@ StageMorph.prototype.paletteTextColor
|
||||||
|
|
||||||
StageMorph.prototype.hiddenPrimitives = {};
|
StageMorph.prototype.hiddenPrimitives = {};
|
||||||
StageMorph.prototype.codeMappings = {};
|
StageMorph.prototype.codeMappings = {};
|
||||||
|
StageMorph.prototype.codeHeaders = {};
|
||||||
StageMorph.prototype.enableCodeMapping = false;
|
StageMorph.prototype.enableCodeMapping = false;
|
||||||
|
|
||||||
// StageMorph instance creation
|
// StageMorph instance creation
|
||||||
|
@ -4047,6 +4054,7 @@ StageMorph.prototype.blockTemplates = function (category) {
|
||||||
blocks.push('=');
|
blocks.push('=');
|
||||||
|
|
||||||
if (StageMorph.prototype.enableCodeMapping) {
|
if (StageMorph.prototype.enableCodeMapping) {
|
||||||
|
blocks.push(block('doMapHeader'));
|
||||||
blocks.push(block('doMapCode'));
|
blocks.push(block('doMapCode'));
|
||||||
blocks.push(block('doMapStringCode'));
|
blocks.push(block('doMapStringCode'));
|
||||||
blocks.push(block('doMapListCode'));
|
blocks.push(block('doMapListCode'));
|
||||||
|
|
38
store.js
38
store.js
|
@ -61,7 +61,7 @@ SyntaxElementMorph*/
|
||||||
|
|
||||||
// Global stuff ////////////////////////////////////////////////////////
|
// Global stuff ////////////////////////////////////////////////////////
|
||||||
|
|
||||||
modules.store = '2013-June-19';
|
modules.store = '2013-July-04';
|
||||||
|
|
||||||
|
|
||||||
// XML_Serializer ///////////////////////////////////////////////////////
|
// XML_Serializer ///////////////////////////////////////////////////////
|
||||||
|
@ -378,6 +378,8 @@ SnapSerializer.prototype.loadProjectModel = function (xmlNode) {
|
||||||
project.stage.setExtent(StageMorph.prototype.dimensions);
|
project.stage.setExtent(StageMorph.prototype.dimensions);
|
||||||
project.stage.isThreadSafe =
|
project.stage.isThreadSafe =
|
||||||
model.stage.attributes.threadsafe === 'true';
|
model.stage.attributes.threadsafe === 'true';
|
||||||
|
StageMorph.prototype.enableCodeMapping =
|
||||||
|
model.stage.attributes.codify === 'true';
|
||||||
|
|
||||||
model.hiddenPrimitives = model.project.childNamed('hidden');
|
model.hiddenPrimitives = model.project.childNamed('hidden');
|
||||||
if (model.hiddenPrimitives) {
|
if (model.hiddenPrimitives) {
|
||||||
|
@ -390,6 +392,13 @@ SnapSerializer.prototype.loadProjectModel = function (xmlNode) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
model.codeHeaders = model.project.childNamed('headers');
|
||||||
|
if (model.codeHeaders) {
|
||||||
|
model.codeHeaders.children.forEach(function (xml) {
|
||||||
|
StageMorph.prototype.codeHeaders[xml.tag] = xml.contents;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
model.codeMappings = model.project.childNamed('code');
|
model.codeMappings = model.project.childNamed('code');
|
||||||
if (model.codeMappings) {
|
if (model.codeMappings) {
|
||||||
model.codeMappings.children.forEach(function (xml) {
|
model.codeMappings.children.forEach(function (xml) {
|
||||||
|
@ -672,7 +681,7 @@ SnapSerializer.prototype.loadCustomBlocks = function (
|
||||||
// private
|
// private
|
||||||
var myself = this;
|
var myself = this;
|
||||||
element.children.forEach(function (child) {
|
element.children.forEach(function (child) {
|
||||||
var definition, names, inputs, code, comment, i;
|
var definition, names, inputs, header, code, comment, i;
|
||||||
if (child.tag !== 'block-definition') {
|
if (child.tag !== 'block-definition') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -711,6 +720,11 @@ SnapSerializer.prototype.loadCustomBlocks = function (
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
header = child.childNamed('header');
|
||||||
|
if (header) {
|
||||||
|
definition.codeHeader = header.contents;
|
||||||
|
}
|
||||||
|
|
||||||
code = child.childNamed('code');
|
code = child.childNamed('code');
|
||||||
if (code) {
|
if (code) {
|
||||||
definition.codeMapping = code.contents;
|
definition.codeMapping = code.contents;
|
||||||
|
@ -1266,20 +1280,20 @@ StageMorph.prototype.toXML = function (serializer) {
|
||||||
thumbdata = null;
|
thumbdata = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function codeMappings() {
|
function code(key) {
|
||||||
var code = '';
|
var str = '';
|
||||||
Object.keys(StageMorph.prototype.codeMappings).forEach(
|
Object.keys(StageMorph.prototype[key]).forEach(
|
||||||
function (selector) {
|
function (selector) {
|
||||||
code += (
|
str += (
|
||||||
'<' + selector + '>' +
|
'<' + selector + '>' +
|
||||||
XML_Element.prototype.escape(
|
XML_Element.prototype.escape(
|
||||||
StageMorph.prototype.codeMappings[selector]
|
StageMorph.prototype[key][selector]
|
||||||
) +
|
) +
|
||||||
'</' + selector + '>'
|
'</' + selector + '>'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
return code;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.removeAllClones();
|
this.removeAllClones();
|
||||||
|
@ -1288,6 +1302,7 @@ StageMorph.prototype.toXML = function (serializer) {
|
||||||
'<notes>$</notes>' +
|
'<notes>$</notes>' +
|
||||||
'<thumbnail>$</thumbnail>' +
|
'<thumbnail>$</thumbnail>' +
|
||||||
'<stage name="@" costume="@" tempo="@" threadsafe="@" ' +
|
'<stage name="@" costume="@" tempo="@" threadsafe="@" ' +
|
||||||
|
'codify="@" ' +
|
||||||
'scheduled="@" ~>' +
|
'scheduled="@" ~>' +
|
||||||
'<pentrails>$</pentrails>' +
|
'<pentrails>$</pentrails>' +
|
||||||
'<costumes>%</costumes>' +
|
'<costumes>%</costumes>' +
|
||||||
|
@ -1297,6 +1312,7 @@ StageMorph.prototype.toXML = function (serializer) {
|
||||||
'<scripts>%</scripts><sprites>%</sprites>' +
|
'<scripts>%</scripts><sprites>%</sprites>' +
|
||||||
'</stage>' +
|
'</stage>' +
|
||||||
'<hidden>$</hidden>' +
|
'<hidden>$</hidden>' +
|
||||||
|
'<headers>%</headers>' +
|
||||||
'<code>%</code>' +
|
'<code>%</code>' +
|
||||||
'<blocks>%</blocks>' +
|
'<blocks>%</blocks>' +
|
||||||
'<variables>%</variables>' +
|
'<variables>%</variables>' +
|
||||||
|
@ -1310,6 +1326,7 @@ StageMorph.prototype.toXML = function (serializer) {
|
||||||
this.getCostumeIdx(),
|
this.getCostumeIdx(),
|
||||||
this.getTempo(),
|
this.getTempo(),
|
||||||
this.isThreadSafe,
|
this.isThreadSafe,
|
||||||
|
this.enableCodeMapping,
|
||||||
StageMorph.prototype.frameRate !== 0,
|
StageMorph.prototype.frameRate !== 0,
|
||||||
this.trailsCanvas.toDataURL('image/png'),
|
this.trailsCanvas.toDataURL('image/png'),
|
||||||
serializer.store(this.costumes, this.name + '_cst'),
|
serializer.store(this.costumes, this.name + '_cst'),
|
||||||
|
@ -1322,7 +1339,8 @@ StageMorph.prototype.toXML = function (serializer) {
|
||||||
function (a, b) {return a + ' ' + b; },
|
function (a, b) {return a + ' ' + b; },
|
||||||
''
|
''
|
||||||
),
|
),
|
||||||
codeMappings(),
|
code('codeHeaders'),
|
||||||
|
code('codeMappings'),
|
||||||
serializer.store(this.globalBlocks),
|
serializer.store(this.globalBlocks),
|
||||||
(ide && ide.globalVariables) ?
|
(ide && ide.globalVariables) ?
|
||||||
serializer.store(ide.globalVariables) : ''
|
serializer.store(ide.globalVariables) : ''
|
||||||
|
@ -1587,6 +1605,7 @@ CustomBlockDefinition.prototype.toXML = function (serializer) {
|
||||||
return serializer.format(
|
return serializer.format(
|
||||||
'<block-definition s="@" type="@" category="@">' +
|
'<block-definition s="@" type="@" category="@">' +
|
||||||
'%' +
|
'%' +
|
||||||
|
'<header>@</header>' +
|
||||||
'<code>@</code>' +
|
'<code>@</code>' +
|
||||||
'<inputs>%</inputs>%%' +
|
'<inputs>%</inputs>%%' +
|
||||||
'</block-definition>',
|
'</block-definition>',
|
||||||
|
@ -1594,6 +1613,7 @@ CustomBlockDefinition.prototype.toXML = function (serializer) {
|
||||||
this.type,
|
this.type,
|
||||||
this.category || 'other',
|
this.category || 'other',
|
||||||
this.comment ? this.comment.toXML(serializer) : '',
|
this.comment ? this.comment.toXML(serializer) : '',
|
||||||
|
this.codeHeader || '',
|
||||||
this.codeMapping || '',
|
this.codeMapping || '',
|
||||||
Object.keys(this.declarations).reduce(function (xml, decl) {
|
Object.keys(this.declarations).reduce(function (xml, decl) {
|
||||||
return xml + serializer.format(
|
return xml + serializer.format(
|
||||||
|
|
10
threads.js
10
threads.js
|
@ -83,7 +83,7 @@ ArgLabelMorph, localize*/
|
||||||
|
|
||||||
// Global stuff ////////////////////////////////////////////////////////
|
// Global stuff ////////////////////////////////////////////////////////
|
||||||
|
|
||||||
modules.threads = '2013-June-18';
|
modules.threads = '2013-July-04';
|
||||||
|
|
||||||
var ThreadManager;
|
var ThreadManager;
|
||||||
var Process;
|
var Process;
|
||||||
|
@ -2291,6 +2291,14 @@ Process.prototype.reportTimer = function () {
|
||||||
blocks - not needed to run or debug Snap
|
blocks - not needed to run or debug Snap
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
Process.prototype.doMapHeader = function (aContext, aString) {
|
||||||
|
if (aContext instanceof Context) {
|
||||||
|
if (aContext.expression instanceof SyntaxElementMorph) {
|
||||||
|
return aContext.expression.mapHeader(aString || '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
Process.prototype.doMapCode = function (aContext, aString) {
|
Process.prototype.doMapCode = function (aContext, aString) {
|
||||||
if (aContext instanceof Context) {
|
if (aContext instanceof Context) {
|
||||||
if (aContext.expression instanceof SyntaxElementMorph) {
|
if (aContext.expression instanceof SyntaxElementMorph) {
|
||||||
|
|
32
widgets.js
32
widgets.js
|
@ -74,7 +74,7 @@ HTMLCanvasElement, fontHeight, SymbolMorph, localize, SpeechBubbleMorph,
|
||||||
ArrowMorph, MenuMorph, isString, isNil, SliderMorph, MorphicPreferences,
|
ArrowMorph, MenuMorph, isString, isNil, SliderMorph, MorphicPreferences,
|
||||||
ScrollFrameMorph*/
|
ScrollFrameMorph*/
|
||||||
|
|
||||||
modules.widgets = '2013-June-25';
|
modules.widgets = '2013-July-04';
|
||||||
|
|
||||||
var PushButtonMorph;
|
var PushButtonMorph;
|
||||||
var ToggleButtonMorph;
|
var ToggleButtonMorph;
|
||||||
|
@ -1680,16 +1680,33 @@ DialogBoxMorph.prototype.promptCode = function (
|
||||||
title,
|
title,
|
||||||
defaultString,
|
defaultString,
|
||||||
world,
|
world,
|
||||||
pic
|
pic,
|
||||||
|
instructions
|
||||||
) {
|
) {
|
||||||
var frame = new ScrollFrameMorph(),
|
var frame = new ScrollFrameMorph(),
|
||||||
text = new TextMorph(defaultString || ''),
|
text = new TextMorph(defaultString || ''),
|
||||||
|
bdy = new AlignmentMorph('column', this.padding),
|
||||||
size = pic ? Math.max(pic.width, 400) : 400;
|
size = pic ? Math.max(pic.width, 400) : 400;
|
||||||
|
|
||||||
this.getInput = function () {
|
this.getInput = function () {
|
||||||
return text.text;
|
return text.text;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function remarkText(string) {
|
||||||
|
return new TextMorph(
|
||||||
|
string,
|
||||||
|
10,
|
||||||
|
null, // style
|
||||||
|
false, // bold
|
||||||
|
null, // italic
|
||||||
|
null, // alignment
|
||||||
|
null, // width
|
||||||
|
null, // font name
|
||||||
|
MorphicPreferences.isFlat ? null : new Point(1, 1),
|
||||||
|
new Color(255, 255, 255) // shadowColor
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
frame.padding = 6;
|
frame.padding = 6;
|
||||||
frame.setWidth(size);
|
frame.setWidth(size);
|
||||||
frame.acceptsDrops = false;
|
frame.acceptsDrops = false;
|
||||||
|
@ -1723,8 +1740,17 @@ DialogBoxMorph.prototype.promptCode = function (
|
||||||
this.key = 'promptCode' + title + defaultString;
|
this.key = 'promptCode' + title + defaultString;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.addBody(frame);
|
bdy.setColor(this.color);
|
||||||
|
bdy.add(frame);
|
||||||
|
if (instructions) {
|
||||||
|
bdy.add(remarkText(instructions));
|
||||||
|
}
|
||||||
|
bdy.fixLayout();
|
||||||
|
|
||||||
|
this.addBody(bdy);
|
||||||
frame.drawNew();
|
frame.drawNew();
|
||||||
|
bdy.drawNew();
|
||||||
|
|
||||||
this.addButton('ok', 'OK');
|
this.addButton('ok', 'OK');
|
||||||
this.addButton('cancel', 'Cancel');
|
this.addButton('cancel', 'Cancel');
|
||||||
this.fixLayout();
|
this.fixLayout();
|
||||||
|
|
Ładowanie…
Reference in New Issue