Merge branch 'berkeley' into lang-zh

dev
ubertao 2016-05-06 10:50:00 +08:00
commit a483edd66e
20 zmienionych plików z 4068 dodań i 229 usunięć

159
blocks.js
Wyświetl plik

@ -137,19 +137,19 @@
*/
/*global Array, BoxMorph,
Color, ColorPaletteMorph, CursorMorph, FrameMorph, Function, HandleMorph,
Math, MenuMorph, Morph, MorphicPreferences, Object, Point, ScrollFrameMorph,
ShadowMorph, String, StringMorph, TextMorph, WorldMorph, contains, degrees,
detect, document, getDocumentPositionOf, isNaN, isString, newCanvas, nop,
parseFloat, radians, useBlurredShadows, SpeechBubbleMorph, modules,
StageMorph, fontHeight, TableFrameMorph, SpriteMorph, Context,
ListWatcherMorph, CellMorph, DialogBoxMorph, BlockInputFragmentMorph,
PrototypeHatBlockMorph, Costume, IDE_Morph, BlockDialogMorph,
BlockEditorMorph, localize, isNil*/
Color, ColorPaletteMorph, FrameMorph, Function, HandleMorph, Math, MenuMorph,
Morph, MorphicPreferences, Object, Point, ScrollFrameMorph, ShadowMorph,
String, StringMorph, TextMorph, WorldMorph, contains, degrees, detect,
document, getDocumentPositionOf, isNaN, isString, newCanvas, nop, parseFloat,
radians, useBlurredShadows, SpeechBubbleMorph, modules, StageMorph,
fontHeight, TableFrameMorph, SpriteMorph, Context, ListWatcherMorph,
CellMorph, DialogBoxMorph, BlockInputFragmentMorph, PrototypeHatBlockMorph,
Costume, IDE_Morph, BlockDialogMorph, BlockEditorMorph, localize, isNil,
isSnapObject, copy*/
// Global stuff ////////////////////////////////////////////////////////
modules.blocks = '2016-March-16';
modules.blocks = '2016-May-04';
var SyntaxElementMorph;
var BlockMorph;
@ -1031,6 +1031,15 @@ SyntaxElementMorph.prototype.labelPart = function (spec) {
true
);
break;
case '%get': // sprites, parts, speciment, clones
part = new InputSlotMorph(
null,
false,
'gettablesMenu',
true
);
part.isStatic = true;
break;
case '%cst':
part = new InputSlotMorph(
null,
@ -1049,7 +1058,7 @@ SyntaxElementMorph.prototype.labelPart = function (spec) {
comic: ['comic'],
duplicate: ['duplicate'],
confetti: ['confetti']
},
},
true
);
part.setContents(['ghost']);
@ -1215,17 +1224,7 @@ SyntaxElementMorph.prototype.labelPart = function (spec) {
part = new InputSlotMorph(
null,
false,
{
number : ['number'],
text : ['text'],
Boolean : ['Boolean'],
list : ['list'],
command : ['command'],
reporter : ['reporter'],
predicate : ['predicate']
// ring : 'ring'
// object : 'object'
},
'typesMenu',
true
);
part.setContents(['number']);
@ -1789,11 +1788,28 @@ SyntaxElementMorph.prototype.showBubble = function (value, exportPic) {
morphToShow.expand(this.parentThatIsA(ScrollFrameMorph).extent());
isClickable = true;
} else if (value instanceof Morph) {
img = value.fullImage();
morphToShow = new Morph();
morphToShow.silentSetWidth(img.width);
morphToShow.silentSetHeight(img.height);
morphToShow.image = img;
if (isSnapObject(value)) {
img = value.thumbnail(new Point(40, 40));
morphToShow = new Morph();
morphToShow.silentSetWidth(img.width);
morphToShow.silentSetHeight(img.height);
morphToShow.image = img;
morphToShow.version = value.version;
morphToShow.step = function () {
if (this.version !== value.version) {
img = value.thumbnail(new Point(40, 40));
this.image = img;
this.version = value.version;
this.changed();
}
};
} else {
img = value.fullImage();
morphToShow = new Morph();
morphToShow.silentSetWidth(img.width);
morphToShow.silentSetHeight(img.height);
morphToShow.image = img;
}
} else if (value instanceof Costume) {
img = value.thumbnail(new Point(40, 40));
morphToShow = new Morph();
@ -3235,7 +3251,14 @@ BlockMorph.prototype.setCategory = function (aString) {
// BlockMorph copying
BlockMorph.prototype.fullCopy = function () {
BlockMorph.prototype.fullCopy = function (forClone) {
if (forClone) {
if (this.hasBlockVars()) {
forClone = false;
} else {
return copy(this);
}
}
var ans = BlockMorph.uber.fullCopy.call(this);
ans.removeHighlight();
ans.isDraggable = true;
@ -3245,21 +3268,15 @@ BlockMorph.prototype.fullCopy = function () {
ans.allChildren().filter(function (block) {
if (block instanceof SyntaxElementMorph) {
block.cachedInputs = null;
if (block instanceof InputSlotMorph) {
block.contents().clearSelection();
} else if (block.definition) {
if (block.definition) {
block.initializeVariables();
}
} else if (block instanceof CursorMorph) {
block.destroy();
}
return !isNil(block.comment);
}).forEach(function (block) {
var cmnt = block.comment.fullCopy();
block.comment = cmnt;
cmnt.block = block;
//block.comment = null;
});
ans.cachedInputs = null;
return ans;
@ -3269,6 +3286,12 @@ BlockMorph.prototype.reactToTemplateCopy = function () {
this.forceNormalColoring();
};
BlockMorph.prototype.hasBlockVars = function () {
return this.anyChild(function (any) {
return any.definition && any.definition.variableNames.length;
});
};
// BlockMorph events
BlockMorph.prototype.mouseClickLeft = function () {
@ -5160,7 +5183,7 @@ ScriptsMorph.prototype.init = function (owner) {
// ScriptsMorph deep copying:
ScriptsMorph.prototype.fullCopy = function () {
ScriptsMorph.prototype.fullCopy = function (forClone) {
var cpy = new ScriptsMorph(),
pos = this.position(),
child;
@ -5169,17 +5192,21 @@ ScriptsMorph.prototype.fullCopy = function () {
}
this.children.forEach(function (morph) {
if (!morph.block) { // omit anchored comments
child = morph.fullCopy();
child.setPosition(morph.position().subtract(pos));
child = morph.fullCopy(forClone);
cpy.add(child);
if (child instanceof BlockMorph) {
child.allComments().forEach(function (comment) {
comment.align(child);
});
if (!forClone) {
child.setPosition(morph.position().subtract(pos));
if (child instanceof BlockMorph) {
child.allComments().forEach(function (comment) {
comment.align(child);
});
}
}
}
});
cpy.adjustBounds();
if (!forClone) {
cpy.adjustBounds();
}
return cpy;
};
@ -7023,7 +7050,7 @@ InputSlotMorph.prototype.messagesMenu = function () {
allNames = [];
stage.children.concat(stage).forEach(function (morph) {
if (morph instanceof SpriteMorph || morph instanceof StageMorph) {
if (isSnapObject(morph)) {
allNames = allNames.concat(morph.allMessageNames());
}
});
@ -7057,7 +7084,7 @@ InputSlotMorph.prototype.messagesReceivedMenu = function () {
allNames = [];
stage.children.concat(stage).forEach(function (morph) {
if (morph instanceof SpriteMorph || morph instanceof StageMorph) {
if (isSnapObject(morph)) {
allNames = allNames.concat(morph.allMessageNames());
}
});
@ -7175,6 +7202,48 @@ InputSlotMorph.prototype.objectsMenu = function () {
return dict;
};
InputSlotMorph.prototype.typesMenu = function () {
var dict = {
number : ['number'],
text : ['text'],
Boolean : ['Boolean'],
list : ['list']
};
if (SpriteMorph.prototype.enableFirstClass) {
dict.sprite = ['sprite'];
}
dict.command = ['command'];
dict.reporter = ['reporter'];
dict.predicate = ['predicate'];
return dict;
};
InputSlotMorph.prototype.gettablesMenu = function () {
var dict = {
neighbors : ['neighbors'],
self : ['self'],
'other sprites' : ['other sprites'],
clones : ['clones'],
'other clones' : ['other clones']
};
if (SpriteMorph.prototype.enableNesting) {
dict.parts = ['parts'];
dict.anchor = ['anchor'];
}
dict.stage = ['stage'];
if (StageMorph.prototype.enableInheritance) {
dict.children = ['children'];
dict.parent = ['parent'];
}
dict.name = ['name'];
dict['dangling?'] = ['dangling?'];
dict['rotation x'] = ['rotation x'];
dict['rotation y'] = ['rotation y'];
dict['center x'] = ['center x'];
dict['center y'] = ['center y'];
return dict;
};
InputSlotMorph.prototype.attributesMenu = function () {
var block = this.parentThatIsA(BlockMorph),
objName = block.inputs()[1].evaluate(),

72
gui.js
Wyświetl plik

@ -65,11 +65,12 @@ BlockExportDialogMorph, BlockImportDialogMorph, SnapTranslator, localize,
List, InputSlotMorph, SnapCloud, Uint8Array, HandleMorph, SVG_Costume,
fontHeight, hex_sha512, sb, CommentMorph, CommandBlockMorph,
BlockLabelPlaceHolderMorph, Audio, SpeechBubbleMorph, ScriptFocusMorph,
XML_Element, WatcherMorph, BlockRemovalDialogMorph, saveAs, TableMorph*/
XML_Element, WatcherMorph, BlockRemovalDialogMorph, saveAs, TableMorph,
isSnapObject*/
// Global stuff ////////////////////////////////////////////////////////
modules.gui = '2016-March-16';
modules.gui = '2016-May-04';
// Declarations
@ -1399,8 +1400,10 @@ IDE_Morph.prototype.createCorral = function () {
frame.alpha = 0;
this.sprites.asArray().forEach(function (morph) {
template = new SpriteIconMorph(morph, template);
frame.contents.add(template);
if (!morph.isClone) {
template = new SpriteIconMorph(morph, template);
frame.contents.add(template);
}
});
this.corral.frame = frame;
@ -1988,6 +1991,7 @@ IDE_Morph.prototype.removeSprite = function (sprite) {
sprite.parts.forEach(function (part) {myself.removeSprite(part); });
idx = this.sprites.asArray().indexOf(sprite) + 1;
this.stage.threads.stopAllForReceiver(sprite);
sprite.corpsify();
sprite.destroy();
this.stage.watchers().forEach(function (watcher) {
if (watcher.object() === sprite) {
@ -2421,6 +2425,20 @@ IDE_Morph.prototype.settingsMenu = function () {
'check to enable\nsprite composition',
true
);
addPreference(
'First-Class Sprites',
function () {
SpriteMorph.prototype.enableFirstClass =
!SpriteMorph.prototype.enableFirstClass;
myself.currentSprite.blocksCache.sensing = null;
myself.currentSprite.paletteCache.sensing = null;
myself.refreshPalette();
},
SpriteMorph.prototype.enableFirstClass,
'uncheck to disable support\nfor first-class sprites',
'check to enable support\n for first-class sprite',
true
);
addPreference(
'Keyboard Editing',
function () {
@ -2471,6 +2489,17 @@ IDE_Morph.prototype.settingsMenu = function () {
false
);
}
addPreference(
'Live coding support',
function () {
Process.prototype.enableLiveCoding =
!Process.prototype.enableLiveCoding;
},
Process.prototype.enableLiveCoding,
'EXPERIMENTAL! uncheck to disable live\ncustom control structures',
'EXPERIMENTAL! check to enable\n live custom control structures',
true
);
menu.addLine(); // everything below this line is stored in the project
addPreference(
'Thread safe scripts',
@ -2799,7 +2828,6 @@ IDE_Morph.prototype.parseResourceFile = function (text) {
return items;
};
// IDE_Morph menu actions
IDE_Morph.prototype.aboutSnap = function () {
@ -2807,7 +2835,7 @@ IDE_Morph.prototype.aboutSnap = function () {
module, btn1, btn2, btn3, btn4, licenseBtn, translatorsBtn,
world = this.world();
aboutTxt = 'Snap! 4.0.6\nBuild Your Own Blocks\n\n'
aboutTxt = 'Snap! 4.0.7.1\nBuild Your Own Blocks\n\n'
+ 'Copyright \u24B8 2016 Jens M\u00F6nig and '
+ 'Brian Harvey\n'
+ 'jens@moenig.org, bh@cs.berkeley.edu\n\n'
@ -3027,6 +3055,7 @@ IDE_Morph.prototype.newProject = function () {
StageMorph.prototype.enableInheritance = false;
StageMorph.prototype.enableSublistIDs = false;
SpriteMorph.prototype.useFlatLineEnds = false;
Process.prototype.enableLiveCoding = false;
this.setProjectName('');
this.projectNotes = '';
this.createStage();
@ -3534,6 +3563,7 @@ IDE_Morph.prototype.rawOpenProjectString = function (str) {
StageMorph.prototype.enableCodeMapping = false;
StageMorph.prototype.enableInheritance = false;
StageMorph.prototype.enableSublistIDs = false;
Process.prototype.enableLiveCoding = false;
if (Process.prototype.isCatchingErrors) {
try {
this.serializer.openProject(
@ -3578,6 +3608,7 @@ IDE_Morph.prototype.rawOpenCloudDataString = function (str) {
StageMorph.prototype.enableCodeMapping = false;
StageMorph.prototype.enableInheritance = false;
StageMorph.prototype.enableSublistIDs = false;
Process.prototype.enableLiveCoding = false;
if (Process.prototype.isCatchingErrors) {
try {
model = this.serializer.parse(str);
@ -3811,15 +3842,19 @@ IDE_Morph.prototype.saveFileAs = function (
IDE_Morph.prototype.saveCanvasAs = function (canvas, fileName, newWindow) {
// Export a Canvas object as a PNG image
// cavas.toBlob() is currently only supported in Firefox and IE
var myself = this;
if (canvas.toBlob) {
canvas.toBlob(function (blob) {
myself.saveFileAs(blob, 'image/png', fileName, newWindow);
});
} else {
this.saveFileAs(canvas.toDataURL(), 'image/png', fileName, newWindow);
}
// Note: This commented out due to poor browser support.
// cavas.toBlob() is currently supported in Firefox, IE, Chrome but
// browsers prevent easily saving the generated files.
// Do not re-enable without revisiting issue #1191
// if (canvas.toBlob) {
// var myself = this;
// canvas.toBlob(function (blob) {
// myself.saveFileAs(blob, 'image/png', fileName, newWindow);
// });
// return;
// }
this.saveFileAs(canvas.toDataURL(), 'image/png', fileName, newWindow);
};
IDE_Morph.prototype.saveXMLAs = function(xml, fileName, newWindow) {
@ -3929,7 +3964,7 @@ IDE_Morph.prototype.toggleZebraColoring = function () {
// select all scripts:
this.stage.children.concat(this.stage).forEach(function (morph) {
if (morph instanceof SpriteMorph || morph instanceof StageMorph) {
if (isSnapObject(morph)) {
scripts = scripts.concat(
morph.scripts.children.filter(function (morph) {
return morph instanceof BlockMorph;
@ -4807,7 +4842,7 @@ IDE_Morph.prototype.getURL = function (url) {
}
throw new Error('unable to retrieve ' + url);
} catch (err) {
myself.showMessage(err);
myself.showMessage(err.toString());
return;
}
};
@ -6298,7 +6333,8 @@ CostumeIconMorph.prototype.editCostume = function () {
} else {
this.object.edit(
this.world(),
this.parentThatIsA(IDE_Morph)
this.parentThatIsA(IDE_Morph),
false // not a new costume, retain existing rotation center
);
}
};

Wyświetl plik

@ -2882,3 +2882,41 @@ end - bulk of 151215
* added web api / https reporter library
* Blocks, Store: New “transient variable” feature
* German translation update
== v4.0.6 ==== - saving linked lists
160502
------
* first class sprites, new MY reporter block and extended functionality of TOUCHING
* fixed switching from list watcher to table view inside sprite speech bubbles
* fixed paint editor automatic rotation center issue
* enhanced functionality to SET a sprites attributes
* execute clone initialization scripts first step in the same frame as the clone command
* auto-repair (sorta) certain broken project files
* Threads: More aggressive emergency yielding
* “corpsify” deleted sprites, which might still be referred to by variables and lists
* Blocks: simplify block copying
* experimental hidden “live-coding support” preference
* updated penTrails library to shrinkWrap generated costumes
demos from the documentation:
http://snap.berkeley.edu/run#cloud:Username=jens&ProjectName=population
http://snap.berkeley.edu/run#present:Username=jens&ProjectName=Woodworm
http://snap.berkeley.edu/run#present:Username=jens&ProjectName=Ferris%20Wheel%202016
http://snap.berkeley.edu/run#cloud:Username=jens&ProjectName=PathFollower
http://snap.berkeley.edu/run#present:Username=jens&ProjectName=cartwheel
http://snap.berkeley.edu/run#cloud:Username=jens&ProjectName=rotation
* new Indonesian translation. Yay!! Thank you, Alexander Liu!!
* Translation updates: Slovenian, Portuguese, Chinese
* minor bug fixes
== v4.0.7 ==== - first class sprites
160504
------
* Morphic, Objects, Blocks, Threads, GUI: Partially shallow-copy clones for speed
* new Estonian translation! Yay!! Thanks, Hasso Tepper!
== v4.0.7.1 ==== - cloning speed-up

Wyświetl plik

@ -185,7 +185,7 @@ SnapTranslator.dict.de = {
'translator_e-mail':
'jens@moenig.org', // optional
'last_changed':
'2016-03-16', // this, too, will appear in the Translators tab
'2016-05-02', // this, too, will appear in the Translators tab
// GUI
// control bar:
@ -527,6 +527,8 @@ SnapTranslator.dict.de = {
'Stoppuhr',
'%att of %spr':
'%att von %spr',
'my %get':
'Attribut %get',
'http:// %s':
'http:// %s',
'turbo mode?':
@ -1352,10 +1354,46 @@ SnapTranslator.dict.de = {
'Funktionsblock',
'predicate':
'Pr\u00e4dikat',
'sprite':
'Objekt',
// list indices
'last':
'letztes',
'any':
'beliebig'
'beliebig',
// attributes
'neighbors':
'Nachbarn',
'self':
'selbst',
'other sprites':
'andere Objekte',
'parts':
'Teile',
'anchor':
'Verankerung',
'parent':
'Vorfahr',
'children':
'Abkömmlinge',
'clones':
'Klone',
'other clones':
'andere Klone',
'dangling?':
'Baumeln?',
'rotation x':
'Drehpunkt x',
'rotation y':
'Drehpunkt y',
'center x':
'Mittelpunkt x',
'center y':
'Mittelpunkt y',
'name':
'Name',
'stage':
'B\u00fchne',
};

1579
lang-et.js 100644

Plik diff jest za duży Load Diff

1360
lang-id.js 100644

Plik diff jest za duży Load Diff

Wyświetl plik

@ -185,7 +185,7 @@ SnapTranslator.dict.pt = {
'translator_e-mail':
'mmsequeira@gmail.com',
'last_changed':
'2016-01-08',
'2016-04-06',
// GUI
// control bar:
@ -815,6 +815,10 @@ SnapTranslator.dict.pt = {
'Design plano',
'Keyboard Editing':
'Edição usando o teclado',
'Table support':
'Suporte de tabelas',
'Table lines':
'Tabelas com linhas',
'Thread safe scripts':
'Guiões seguros face a threads',
'uncheck to allow\nscript reentrance':
@ -877,6 +881,12 @@ SnapTranslator.dict.pt = {
'adicionar anel',
'unringify':
'remover anel',
'transient':
'transiente',
'uncheck to save contents\nin the project':
'Desassinalar para guardar\no conteúdo no projecto',
'check to prevent contents\nfrom being saved':
'Assinalar para não guardar\no conteúdo no projecto',
// blocos personalizados:
'delete block definition...':
@ -942,6 +952,18 @@ SnapTranslator.dict.pt = {
'rename sound':
'Qual o novo nome do som?',
// lists and tables
'list view...':
'vista de lista…',
'table view...':
'vista de tabela…',
'open in dialog...':
'abrir em caixa de diálogo…',
'reset columns':
'reiniciar colunas',
'items':
'itens',
// caixas de diálogo
// botões
'OK':
@ -1746,6 +1768,22 @@ SnapTranslator.dict.pt = {
'com variáveis de bloco',
'experimental -\nunder construction':
'Experimental – em construção',
'Table view':
'Vista de tabela',
'open in another dialog...':
'abrir noutra caixa de diálogo…',
'check for multi-column\nlist view support':
'Assinalar para suporte de\nvistas multicoluna de listas.',
'uncheck to disable\nmulti-column list views':
'Desassinalar para desactivar\nvistas multicoluna de listas.',
'check for higher contrast\ntable views':
'Assinalar para vistas de\ntabela com maior contraste.',
'uncheck for less contrast\nmulti-column list views':
'Desassinalar para vistas multicoluna\nde listas com menor contraste.',
'(in a new window)':
'(numa nova janela)',
'save project data as XML\nto your downloads folder':
'Guardar dados do projecto como XML\nna sua pasta de descarregamentos.',
// produção de código
'map %cmdRing to %codeKind %code':

Wyświetl plik

@ -183,11 +183,11 @@ SnapTranslator.dict.si = {
'language_name':
'Sloven\u0161\u010Dina', // the name as it should appear in the language menu
'language_translator':
'Sasa Divjak', // your name for the Translators tab
'Sasa Divjak, Gorazd Breskvar', // your name for the Translators tab
'translator_e-mail':
'sasa.divjak@fri.uni-lj.si', // optional
'last_changed':
'2013-01-07', // this, too, will appear in the Translators tab
'2016-04-22', // this, too, will appear in the Translators tab
// GUI
// control bar:
@ -378,6 +378,16 @@ SnapTranslator.dict.si = {
'predvajaj zvok %snd do konca',
'stop all sounds':
'ustavi vse zvoke',
'rest for %n beats':
'po\u010Divaj %n udarcev',
'play note %n for %n beats':
'predvajaj noto %n za %n udarcev',
'change tempo by %n':
'spremeni tempo za %n',
'set tempo to %n bpm':
'nastavi tempo na %n udarcev na minuto.',
'tempo':
'tempo',
// pen:
'clear':
@ -408,8 +418,20 @@ SnapTranslator.dict.si = {
'ko kliknemo na %greenflag',
'when %keyHat key pressed':
'ko pritisnemo na tipko %keyHat ',
'when I am clicked':
'ko je klik name',
'when I am %interaction':
'Ko je %interaction',
'clicked':
'mi\u0161ka kliknjena',
'pressed':
'gumb mi\u0161ke pritisnjen',
'dropped':
'konec vle\u010Denja',
'mouse-entered':
'mi\u0161ka se dotika',
'mouse-departed':
'mi\u0161ka se ne dotika ve\u010D',
'when %b':
'Ko je %b',
'when I receive %msgHat':
'ko sprejmem %msgHat',
'broadcast %msg':
@ -418,6 +440,10 @@ SnapTranslator.dict.si = {
'po\u0161lji vsem %msg in po\u010Dakaj',
'Message name':
'Obvestilo',
'message':
'sporo\u010Dilo',
'any message':
'poljudno sporo\u010Dilo',
'wait %n secs':
'\u010Dakaj %n sekund.',
'wait until %b':
@ -434,12 +460,20 @@ SnapTranslator.dict.si = {
'\u010De %b %c sicer %c',
'report %s':
'sporo\u010Di %s',
'stop block':
'ustavi ta blok',
'stop script':
'ustavi ta program',
'stop all %stop':
'ustavi vse %stop',
'stop %stopChoices':
'ustavi %stopChoices',
'this script':
'to skripto',
'this block':
'ta blok',
'stop %stopOthersChoices':
'ustavi %stopOthersChoices',
'all but this script':
'vse razen te skripte',
'other scripts in sprite':
'ostale skripte tega objekta',
'pause all %pause':
'pavziraj vse %pause',
'run %cmdRing %inputs':
'izvajaj %cmdRing %inputs',
'launch %cmdRing %inputs':
@ -452,6 +486,14 @@ SnapTranslator.dict.si = {
'pokli\u010Di %cmdRing z nadaljevanjem',
'warp %c':
'Warp %c',
'when I start as a clone':
'ko za\u010Dnem kot klon',
'create a clone of %cln':
'kloniraj %cln',
'myself':
'sebe',
'delete this clone':
'izbri\u0161i ta klon',
// sensing:
'touching %col ?':
@ -482,6 +524,30 @@ SnapTranslator.dict.si = {
'\u0161toparica',
'http:// %s':
'http:// %s',
'turbo mode?':
'hitri na\u010Din?',
'set turbo mode to %b':
'nastavi hitri na\u010Din na %b',
'current %dates':
'trenutni %dates',
'year':
'leto',
'month':
'mesec',
'date':
'dan',
'day of week':
'dan v tednu',
'hour':
'ura',
'minute':
'minuta',
'second':
'sekunda',
'time in milliseconds':
'\u010Das v tiso\u010Dinkah sekunde',
'filtered for %clr':
'filtriran za %clr',
@ -511,6 +577,8 @@ SnapTranslator.dict.si = {
'ni res',
'join %words':
'pove\u017Ei %words',
'split %s by %delim':
'razdeli %s z %delim',
'hello':
'Halo',
'world':
@ -525,6 +593,8 @@ SnapTranslator.dict.si = {
'Unicode %n kot \u010Drka',
'is %s a %typ ?':
'je %s tipa %typ ?',
'is %s identical to %s ?':
'je %s identi\u010Den %s ?',
'type of %s':
'Tip od %s',
@ -580,6 +650,8 @@ SnapTranslator.dict.si = {
// snap menu
'About...':
'Nekaj o Snap!...',
'Reference manual':
'Uporabni\u0161ka navodila',
'Snap! website':
'Spletna stran Snap!',
'Download source':
@ -602,6 +674,11 @@ SnapTranslator.dict.si = {
'Odpri...',
'Save':
'Shrani',
'Save to disk':
'Shrani na disk',
'store this project\nin the downloads folder\n(in supporting browsers)':
'shrani v mapo Prenosi\n'
+ '(ni na voljo v vseh brkljalnika)',
'Save As...':
'Shrani kot...',
'Import...':
@ -620,10 +697,50 @@ SnapTranslator.dict.si = {
'Izvozi bloke',
'show global custom block definitions as XML\nin a new browser window':
'Prikaz definicij globalnih lastnih blokov kot XML\nv novem oknu brkljalnika',
'Unused blocks...':
'Neuporabljeni bloki...',
'find unused global custom blocks\nand remove their definitions':
'najdi in odstrani uporabni\u0161ke neuporabljene globalne bloke',
'Remove unused blocks':
'Odstrani neuporabljene bloke',
'there are currently no unused\nglobal custom blocks in this project':
'trenutno ni neuporabljenih globalnih blokov v tem projektu',
'unused block(s) removed':
'neuporabljeni bloki so bili odstranjeni',
'Export summary...':
'Povzetek izvoza...',
'Import tools':
'Uvozi orodja',
'load the official library of\npowerful blocks':
'uvozi uradni modul z naprednimi bloki',
'Libraries...':
'Knji\u017Enice...',
'Import library':
'Nalo\u017Ei knji\u017Enico',
// cloud menu
'Login...':
'Prijava...',
'Signup...':
'Registracija...',
'Reset Password...':
'Pozabljeno geslo...',
// settings menu
'Language...':
'Jezik...',
'Zoom blocks...':
'Pove\u010Daj bloke...',
'Stage size...':
'Velikost scene...',
'Stage size':
'Velikost scene',
'Stage width':
'\u0160irina scene',
'Stage height':
'Vi\u0161ina scene',
'Default':
'Normalno',
'Blurred shadows':
'Mehke sence',
'uncheck to use solid drop\nshadows and highlights':
@ -637,9 +754,9 @@ SnapTranslator.dict.si = {
'uncheck to disable alternating\ncolors for nested block':
'izklopi izmenjujo\u010De barve gnezdenih blokov',
'Prefer empty slot drops':
'Imejmo raje prazne reže',
'Imejmo raje prazne re\u017Ee',
'settings menu prefer empty slots hint':
'vklop raje namiga za prazne reže'
'vklop raje namiga za prazne re\u017Ee'
+ 'zu bevorzugen',
'uncheck to allow dropped\nreporters to kick out others':
'razkljukaj za to, da reporterji odrinejo druge',
@ -667,12 +784,46 @@ SnapTranslator.dict.si = {
'razkljukaj za deaktiviranje akusti\u010Dnega klikanja',
'check to turn\nblock clicking\nsound on':
'odkljukaj za vklop akusti\u010Dnega klikanja',
'Animations':
'Animacije',
'uncheck to disable\nIDE animations':
'razkljukaj za izklop IDE animacij',
'Turbo mode':
'Hitri na\u010Din',
'check to prioritize\nscript execution':
'odkljukaj za ve\u010Djo prioriteto izvajanja skript',
'uncheck to run scripts\nat normal speed':
'razkljukaj za normalno hitrost izvajanja skript',
'check to enable\nIDE animations':
'odkljukaj za IDE animacije',
'Flat design':
'Svetli izgled',
'Keyboard Editing':
'Urejanje s tipkovnico',
'Table support':
'Podpora za tabele',
'Table lines':
'\u010Crte med celicami v tabeli',
'Thread safe scripts':
'Varnost niti',
'uncheck to allow\nscript reentrancy':
'uncheck to allow\nscript reentrance':
'razkljukaj za dopu\u0161\u010Danje ve\u010Dkraten vstop skript (reentrancy)',
'check to disallow\nscript reentrancy':
'check to disallow\nscript reentrance':
'odkljukaj za onemogo\u010Danje ve\u010Dkratnega vstopa skript',
'Prefer smooth animations':
'Gladka animacija',
'uncheck for greater speed\nat variable frame rates':
'razkljukaj za hitrej\u0161e animacije s spremenljivo hitrostjo osve\u017Eevanja',
'check for smooth, predictable\nanimations across computers':
'odkljukaj za bolj predvidljivo hitrost animacij med razli\u010Dnimi ra\u010Dunalniki',
'Flat line ends':
'Ravni zaklju\u010Dki \u010Drt',
'check for flat ends of lines':
'odkljukaj za ravne zaklju\u010Dke \u010Drt',
'uncheck for round ends of lines':
'razkljukaj za zaobljene zaklju\u010Dke \u010Drt',
'Inheritance support':
'Podpora za dedovanje',
// inputs
'with inputs':
@ -681,18 +832,30 @@ SnapTranslator.dict.si = {
'imena vhodov:',
'Input Names:':
'imena vhodov:',
'input list:':
'vhodni seznam:',
// context menus:
'help':
'Pomo\u010D',
'Pomo\u010D...',
// palette:
'hide primitives':
'skrij osnovne bloke',
'show primitives':
'poka\u017Ei osnovne bloke',
// blocks:
'help...':
'Pomo\u010D...',
'pomo\u010D...',
'relabel...':
'spremeni tip...',
'duplicate':
'podvoji',
'make a copy\nand pick it up':
'kopiraj',
'only duplicate this block':
'podvoji ta blok',
'delete':
'bri\u0161i',
'script pic...':
@ -703,6 +866,8 @@ SnapTranslator.dict.si = {
'Obkro\u017Ei',
'unringify':
'odstrani obro\u010D',
'transient':
'se ne shranjuje',
// custom blocks:
'delete block definition...':
@ -713,9 +878,23 @@ SnapTranslator.dict.si = {
// sprites:
'edit':
'uredi',
'move':
'premakni',
'detach from':
'odklopi',
'detach all parts':
'odklopi vse dele',
'export...':
'izvozi...',
// stage:
'show all':
'prila\u017Ei vse ',
'pic...':
'izvozi sliko...',
'open a new window\nwith a picture of the stage':
'odpri novo okno s sliko te scene',
// scripting area
'clean up':
'po\u010Disti',
@ -723,6 +902,14 @@ SnapTranslator.dict.si = {
'uredi skripte vertikalno',
'add comment':
'dodaj komentar',
'undrop':
'ponovno povle\u010Di',
'undo the last\nblock drop\nin this pane':
'prekli\u010Di dodajanje zadnjega bloka v tem okviru',
'scripts pic...':
'slika skript...',
'open a new window\nwith a picture of all scripts':
'odpri novo okno s sliko vseh skript',
'make a block...':
'Gradnja novega bloka...',
@ -731,6 +918,8 @@ SnapTranslator.dict.si = {
'preimenuj',
'export':
'izvozi',
'rename costume':
'preimenuj izgled',
// sounds
'Play sound':
@ -741,11 +930,25 @@ SnapTranslator.dict.si = {
'Ustavi',
'Play':
'Predvajaj',
'rename sound':
'Preimenuj zvok',
// lists and tables
'list view...':
'prika\u017Ei kot seznam...',
'table view...':
'prika\u017Ei kot tabelo',
'open in dialog...':
'odpri v novem oknu',
'items':
'elementi',
// dialogs
// buttons
'OK':
'V redu',
'Ok':
'V redu',
'Cancel':
'Prekli\u010Di',
'Yes':
@ -757,6 +960,46 @@ SnapTranslator.dict.si = {
'Help':
'Pomo\u010D',
// zoom blocks
'Zoom blocks':
'Pove\u010Daj blok',
'build':
'zgradi',
'your own':
'svoj',
'blocks':
'blok',
'normal (1x)':
'normalno (1x)',
'demo (1.2x)':
'demo (1.2x)',
'presentation (1.4x)':
'predstavitev(1.4x)',
'big (2x)':
'veliko (2x)',
'huge (4x)':
've\u010Dje(4x)',
'giant (8x)':
'ogromno (8x)',
'monstrous (10x)':
'najve\u010Dje(10x)',
// Project Manager
'Untitled':
'Neimenovano',
'Open Project':
'Odpri projekt',
'(empty)':
'(prazno)',
'Saved!':
'Shranjeno!',
'Delete Project':
'Zbri\u0161i projekt',
'Are you sure you want to delete':
'Ste prepri\u010Dani da \u017Eelite izbrisati?',
'rename...':
'preimenuj...',
// costume editor
'Costume Editor':
'Urejevalnik oblek',
@ -773,10 +1016,6 @@ SnapTranslator.dict.si = {
'Replace the current project with a new one?':
'Zamenjam trenutni projekt z novim?',
// open project
'Open Project':
'Odpri projekt',
// save project
'Save Project As...':
'Shrani projekt kot...',
@ -784,6 +1023,8 @@ SnapTranslator.dict.si = {
// export blocks
'Export blocks':
'Izvoz blokov',
'Import blocks':
'Uvoz blokov',
'this project doesn\'t have any\ncustom global blocks yet':
'ta projekt \u0161e nima lastnih globalnih blokov',
'select':
@ -827,6 +1068,8 @@ SnapTranslator.dict.si = {
'Tvori ime vhoda',
'Edit input name':
'Uredi ime vhoda',
'Edit label fragment':
'Uredi ime dela',
'Title text':
'Naslovno besedilo',
'Input name':
@ -895,6 +1138,8 @@ SnapTranslator.dict.si = {
'min vrednost...',
'slider max...':
'maks vrednost...',
'import...':
'uvozi...',
'Slider minimum value':
'Minimalna vrednost drsnika',
'Slider maximum value':
@ -930,11 +1175,16 @@ SnapTranslator.dict.si = {
// costumes
'Turtle':
'Kazalec smeri',
'Empty':
'Prazno',
// graphical effects
'brightness':
'svetlost',
'ghost':
'prosojnost',
'negative':
'obratno',
// keys
'space':
'presledek',
@ -946,6 +1196,8 @@ SnapTranslator.dict.si = {
'pu\u0161\u010Dica desno',
'left arrow':
'pu\u0161\u010Dica levo',
'any key':
'poljuden',
'a':
'a',
'b':
@ -1026,6 +1278,10 @@ SnapTranslator.dict.si = {
// math functions
'abs':
'abs',
'ceiling':
'zaokro\u017Eevanje navzgor',
'floor':
'zaokro\u017Eevanje navzdol',
'sqrt':
'koren',
'sin':
@ -1045,6 +1301,16 @@ SnapTranslator.dict.si = {
'e^':
'e^',
// delimiters
'letter':
'\u010Drke',
'whitespace':
'presledki',
'line':
'vrstica',
'tab':
'tab',
// data types
'number':
'\u0161tevilo',

Wyświetl plik

@ -7,4 +7,4 @@ word-sentence.xml Words, sentences
cases.xml Multi-branched conditional (switch)
leap-library.xml LEAP Motion controller
setrgb.xml Set RGB or HSV pen color
penTrails.xml Save and restore pictures drawn by pen
penTrails.xml Save and restore pictures drawn by pen

File diff suppressed because one or more lines are too long

Wyświetl plik

@ -1 +1 @@
<blocks app="Snap! 4.0, http://snap.berkeley.edu" version="1"><block-definition s="pen trails" type="reporter" category="pen"><header></header><code></code><inputs></inputs><script><block s="doReport"><block s="evaluate"><block s="reportJSFunction"><list></list><l>return new Costume(&#xD; this.parentThatIsA(StageMorph).trailsCanvas&#xD;);</l></block><list></list></block></block></script></block-definition><block-definition s="set pen trails to: %&apos;costume&apos;" type="command" category="pen"><header></header><code></code><inputs><input type="%s" readonly="true"></input></inputs><script><block s="doRun"><block s="reportJSFunction"><list><l>cst</l></list><l>var stage = this.parentThatIsA(StageMorph);&#xD;stage.trailsCanvas = cst.contents;&#xD;stage.changed();</l></block><list><block var="costume"/></list></block></script></block-definition></blocks>
<blocks app="Snap! 4.0, http://snap.berkeley.edu" version="1"><block-definition s="pen trails" type="reporter" category="pen"><header></header><code></code><inputs></inputs><script><block s="doReport"><block s="evaluate"><block s="reportJSFunction"><list></list><l>var cst = new Costume(&#xD; this.parentThatIsA(StageMorph).trailsCanvas&#xD;);&#xD;cst.shrinkWrap();&#xD;return cst;</l></block><list></list></block></block></script></block-definition><block-definition s="set pen trails to: %&apos;costume&apos;" type="command" category="pen"><header></header><code></code><inputs><input type="%s" readonly="true"></input></inputs><script><block s="doRun"><block s="reportJSFunction"><list><l>cst</l></list><l>var stage = this.parentThatIsA(StageMorph);&#xD;stage.trailsCanvas = cst.contents;&#xD;stage.changed();</l></block><list><block var="costume"/></list></block></script></block-definition></blocks>

Wyświetl plik

@ -60,9 +60,9 @@
Color, Point, WatcherMorph, StringMorph, SpriteMorph, ScrollFrameMorph,
CellMorph, ArrowMorph, MenuMorph, snapEquals, Morph, isNil, localize,
MorphicPreferences, TableDialogMorph, SpriteBubbleMorph, SpeechBubbleMorph,
TableFrameMorph, TableMorph, Variable*/
TableFrameMorph, TableMorph, Variable, isSnapObject*/
modules.lists = '2016-February-24';
modules.lists = '2016-May-02';
var List;
var ListWatcherMorph;
@ -322,6 +322,27 @@ List.prototype.asArray = function () {
return this.contents;
};
List.prototype.itemsArray = function () {
// answer an array containing my elements
// don't convert linked lists to arrays
if (this.isLinked) {
var next = this,
result = [],
i;
while (next && next.isLinked) {
result.push(next.first);
next = next.rest;
}
if (next) {
for (i = 1; i <= next.contents.length; i += 1) {
result.push(next.at(i));
}
}
return result;
}
return this.contents;
};
List.prototype.asText = function () {
var result = '',
length,
@ -353,17 +374,7 @@ List.prototype.asText = function () {
List.prototype.becomeArray = function () {
if (this.isLinked) {
var next = this, i;
this.contents = [];
while (next && next.isLinked) {
this.contents.push(next.first);
next = next.rest;
}
if (next) {
for (i = 1; i <= next.contents.length; i += 1) {
this.contents.push(next.at(i));
}
}
this.contents = this.itemsArray();
this.isLinked = false;
this.first = null;
this.rest = null;
@ -543,10 +554,12 @@ ListWatcherMorph.prototype.update = function (anyway) {
starttime, maxtime = 1000;
this.frame.contents.children.forEach(function (m) {
if (m instanceof CellMorph
&& m.contentsMorph instanceof ListWatcherMorph) {
m.contentsMorph.update();
if (m instanceof CellMorph) {
if (m.contentsMorph instanceof ListWatcherMorph) {
m.contentsMorph.update();
} else if (isSnapObject(m.contents)) {
m.update();
}
}
});
@ -802,7 +815,7 @@ ListWatcherMorph.prototype.showTableView = function () {
if (!view) {return; }
if (view instanceof SpriteBubbleMorph) {
view.changed();
view.drawNew();
view.drawNew(true);
} else if (view instanceof SpeechBubbleMorph) {
view.contents = new TableFrameMorph(new TableMorph(this.list, 10));
view.contents.expand(this.extent());

Wyświetl plik

@ -42,7 +42,7 @@
/*global modules, contains*/
modules.locale = '2016-March-16';
modules.locale = '2016-May-04';
// Global stuff
@ -153,7 +153,6 @@ SnapTranslator.dict.en = {
};
SnapTranslator.dict.de = {
// meta information
'language_name':
'Deutsch',
'language_translator':
@ -161,11 +160,10 @@ SnapTranslator.dict.de = {
'translator_e-mail':
'jens@moenig.org',
'last_changed':
'2016-03-16'
'2016-05-02'
};
SnapTranslator.dict.it = {
// meta information
'language_name':
'Italiano',
'language_translator':
@ -177,7 +175,6 @@ SnapTranslator.dict.it = {
};
SnapTranslator.dict.ja = {
// meta information
'language_name':
'日本語',
'language_translator':
@ -189,7 +186,6 @@ SnapTranslator.dict.ja = {
};
SnapTranslator.dict.ja_HIRA = {
// meta information
'language_name':
'にほんご',
'language_translator':
@ -201,7 +197,6 @@ SnapTranslator.dict.ja_HIRA = {
};
SnapTranslator.dict.ko = {
// meta information
'language_name':
'한국어',
'language_translator':
@ -213,7 +208,6 @@ SnapTranslator.dict.ko = {
};
SnapTranslator.dict.pt = {
// meta information
'language_name':
'Português',
'language_translator':
@ -225,7 +219,6 @@ SnapTranslator.dict.pt = {
};
SnapTranslator.dict.cs = {
// meta information
'language_name':
'Česky',
'language_translator':
@ -237,7 +230,6 @@ SnapTranslator.dict.cs = {
};
SnapTranslator.dict.zh = {
// meta information
'language_name':
'简体中文',
'language_translator':
@ -249,7 +241,6 @@ SnapTranslator.dict.zh = {
};
SnapTranslator.dict.eo = {
// meta information
'language_name':
'Esperanto',
'language_translator':
@ -261,7 +252,6 @@ SnapTranslator.dict.eo = {
};
SnapTranslator.dict.fr = {
// meta information
'language_name':
'Fran\u00E7ais',
'language_translator':
@ -273,19 +263,17 @@ SnapTranslator.dict.fr = {
};
SnapTranslator.dict.si = {
// meta information
'language_name':
'Sloven\u0161\u010Dina',
'language_translator':
'Sasa Divjak',
'Sasa Divjak, Gorazd Breskvar',
'translator_e-mail':
'sasa.divjak@fri.uni-lj.si',
'last_changed':
'2013-01-07'
'2016-04-22'
};
SnapTranslator.dict.ru = {
// meta information
'language_name':
'Русский',
'language_translator':
@ -297,7 +285,6 @@ SnapTranslator.dict.ru = {
};
SnapTranslator.dict.es = {
// meta information
'language_name':
'Espa\u00F1ol',
'language_translator':
@ -309,7 +296,6 @@ SnapTranslator.dict.es = {
};
SnapTranslator.dict.nl = {
// meta information
'language_name':
'Nederlands',
'language_translator':
@ -321,7 +307,6 @@ SnapTranslator.dict.nl = {
};
SnapTranslator.dict.pl = {
// meta information
'language_name':
'Polski',
'language_translator':
@ -333,7 +318,6 @@ SnapTranslator.dict.pl = {
};
SnapTranslator.dict.tw = {
// meta information
'language_name':
'繁體中文',
'language_translator':
@ -345,7 +329,6 @@ SnapTranslator.dict.tw = {
};
SnapTranslator.dict.no = {
// meta information
'language_name':
'Norsk',
'language_translator':
@ -357,7 +340,6 @@ SnapTranslator.dict.no = {
};
SnapTranslator.dict.dk = {
// meta information
'language_name':
'Dansk',
'language_translator':
@ -369,7 +351,6 @@ SnapTranslator.dict.dk = {
};
SnapTranslator.dict.el = {
// meta information
'language_name':
'Ελληνικά',
'language_translator':
@ -381,7 +362,6 @@ SnapTranslator.dict.el = {
};
SnapTranslator.dict.ca = {
// meta information
'language_name':
'Català',
'language_translator':
@ -393,7 +373,6 @@ SnapTranslator.dict.ca = {
};
SnapTranslator.dict.fi = {
// meta information
'language_name':
'suomi',
'language_translator':
@ -405,7 +384,6 @@ SnapTranslator.dict.fi = {
};
SnapTranslator.dict.sv = {
// meta information
'language_name':
'svenska',
'language_translator':
@ -417,7 +395,6 @@ SnapTranslator.dict.sv = {
};
SnapTranslator.dict.pt_BR = {
// meta information
'language_name':
'Português do Brasil',
'language_translator':
@ -429,7 +406,6 @@ SnapTranslator.dict.pt_BR = {
};
SnapTranslator.dict.bn = {
// meta information
'language_name':
'বাংলা',
'language_translator':
@ -441,7 +417,6 @@ SnapTranslator.dict.bn = {
};
SnapTranslator.dict.kn = {
// translations meta information
'language_name':
'\u0C95\u0CA8\u0CCD\u0CA8\u0CA1',
'language_translator':
@ -453,7 +428,6 @@ SnapTranslator.dict.kn = {
};
SnapTranslator.dict.ml = {
// translations meta information
'language_name':
'Malayalam',
'language_translator':
@ -465,7 +439,6 @@ SnapTranslator.dict.ml = {
};
SnapTranslator.dict.ta = {
// translations meta information
'language_name':
'Tamil',
'language_translator':
@ -477,7 +450,6 @@ SnapTranslator.dict.ta = {
};
SnapTranslator.dict.te = {
// translations meta information
'language_name':
'Telagu', // the name as it should appear in the language menu
'language_translator':
@ -489,7 +461,6 @@ SnapTranslator.dict.te = {
};
SnapTranslator.dict.tr = {
// translations meta information
'language_name':
'Türkçe',
'language_translator':
@ -501,7 +472,6 @@ SnapTranslator.dict.tr = {
};
SnapTranslator.dict.hu = {
// translations meta information
'language_name':
'Magyar',
'language_translator':
@ -513,7 +483,6 @@ SnapTranslator.dict.hu = {
};
SnapTranslator.dict.ia = {
// translations meta information
'language_name':
'Interlingua',
'language_translator':
@ -566,4 +535,26 @@ SnapTranslator.dict.ar = {
'tarekgalal46@hotmail.com', // optional
'last_changed':
'2016-02-24'
};
};
SnapTranslator.dict.id = {
'language_name':
'Bahasa Indonesia',
'language_translator':
'Alexander Raphael Liu',
'translator_e-mail':
'raphaxander@gmail.com',
'last_changed':
'2016-5-2'
};
SnapTranslator.dict.et = {
'language_name':
'Eesti',
'language_translator':
'Hasso Tepper',
'translator_e-mail':
'hasso.tepper@gmail.com',
'last_changed':
'2016-05-03'
};

Wyświetl plik

@ -337,7 +337,7 @@
(c) an application
-------------------
Of course, most of the time you don't want to just plain use the
standard Morhic World "as is" out of the box, but write your own
standard Morphic World "as is" out of the box, but write your own
application (something like Scratch!) in it. For such an
application you'll create your own morph prototypes, perhaps
assemble your own "window frame" and bring it all to life in a
@ -1054,10 +1054,9 @@
// Global settings /////////////////////////////////////////////////////
/*global window, HTMLCanvasElement, getMinimumFontHeight, FileReader, Audio,
FileList, getBlurredShadowSupport*/
/*global window, HTMLCanvasElement, FileReader, Audio, FileList*/
var morphicVersion = '2016-February-24';
var morphicVersion = '2016-May-04';
var modules = {}; // keep track of additional loaded modules
var useBlurredShadows = getBlurredShadowSupport(); // check for Chrome-bug
@ -1938,7 +1937,7 @@ Rectangle.prototype.round = function () {
Rectangle.prototype.spread = function () {
// round me by applying floor() to my origin and ceil() to my corner
// expand by 1 to be on the safe side, this eliminates rounding
// artefacts caused by Safari's auto-scaling on retina displays
// artifacts caused by Safari's auto-scaling on retina displays
return this.origin.floor().corner(this.corner.ceil()).expandBy(1);
};
@ -2090,6 +2089,20 @@ Node.prototype.forAllChildren = function (aFunction) {
aFunction.call(null, this);
};
Node.prototype.anyChild = function (aPredicate) {
// includes myself
var i;
if (aPredicate.call(null, this)) {
return true;
}
for (i = 0; i < this.children.length; i += 1) {
if (this.children[i].anyChild(aPredicate)) {
return true;
}
}
return false;
};
Node.prototype.allLeafs = function () {
var result = [];
this.allChildren().forEach(function (element) {

Wyświetl plik

@ -82,7 +82,7 @@ SpeechBubbleMorph, RingMorph, isNil, FileReader, TableDialogMorph,
BlockEditorMorph, BlockDialogMorph, PrototypeHatBlockMorph, localize,
TableMorph, TableFrameMorph*/
modules.objects = '2016-March-16';
modules.objects = '2016-May-04';
var SpriteMorph;
var StageMorph;
@ -98,6 +98,10 @@ var StagePrompterMorph;
var Note;
var SpriteHighlightMorph;
function isSnapObject(thing) {
return thing instanceof SpriteMorph || (thing instanceof StageMorph);
}
// SpriteMorph /////////////////////////////////////////////////////////
// I am a scriptable object
@ -144,6 +148,7 @@ SpriteMorph.prototype.sliderColor
SpriteMorph.prototype.isCachingPrimitives = true;
SpriteMorph.prototype.enableNesting = true;
SpriteMorph.prototype.enableFirstClass = true;
SpriteMorph.prototype.useFlatLineEnds = false;
SpriteMorph.prototype.highlightColor = new Color(250, 200, 130);
SpriteMorph.prototype.highlightBorder = 8;
@ -863,6 +868,12 @@ SpriteMorph.prototype.initBlocks = function () {
category: 'sensing',
spec: 'current %dates'
},
reportGet:{
type: 'reporter',
category: 'sensing',
spec: 'my %get',
defaults: [['neighbors']]
},
// Operators
reifyScript: {
@ -1310,6 +1321,7 @@ SpriteMorph.prototype.init = function (globals) {
this.rotationStyle = 1; // 1 = full, 2 = left/right, 0 = off
this.version = Date.now(); // for observer optimization
this.isClone = false; // indicate a "temporary" Scratch-style clone
this.isCorpse = false; // indicate whether a sprite/clone has been deleted
this.cloneOriginName = '';
// sprite nesting properties
@ -1352,31 +1364,32 @@ SpriteMorph.prototype.init = function (globals) {
// SpriteMorph duplicating (fullCopy)
SpriteMorph.prototype.fullCopy = function () {
SpriteMorph.prototype.fullCopy = function (forClone) {
var c = SpriteMorph.uber.fullCopy.call(this),
myself = this,
arr = [],
dp,
cb;
c.stopTalking();
c.color = this.color.copy();
c.blocksCache = {};
c.paletteCache = {};
c.scripts = this.scripts.fullCopy();
c.scripts = this.scripts.fullCopy(forClone);
c.scripts.owner = c;
c.variables = this.variables.copy();
c.variables.owner = c;
c.customBlocks = [];
this.customBlocks.forEach(function (def) {
cb = def.copyAndBindTo(c);
c.customBlocks.push(cb);
c.allBlockInstances(def).forEach(function (block) {
block.definition = cb;
if (!forClone) {
this.customBlocks.forEach(function (def) {
cb = def.copyAndBindTo(c);
c.customBlocks.push(cb);
c.allBlockInstances(def).forEach(function (block) {
block.definition = cb;
});
});
});
}
this.costumes.asArray().forEach(function (costume) {
var cst = costume.copy();
var cst = forClone ? costume : costume.copy();
arr.push(cst);
if (costume === myself.costume) {
c.costume = cst;
@ -1393,21 +1406,22 @@ SpriteMorph.prototype.fullCopy = function () {
c.anchor = null;
c.parts = [];
this.parts.forEach(function (part) {
dp = part.fullCopy();
var dp = part.fullCopy(forClone);
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);
if (!this.isClone) {
this.name = ide.newSpriteName(this.name);
ide.corral.addSprite(this);
ide.sprites.add(this);
}
ide.stage.add(this);
ide.sprites.add(this);
ide.corral.addSprite(this);
this.parts.forEach(function (part) {
part.appearIn(ide);
});
@ -1531,7 +1545,7 @@ SpriteMorph.prototype.drawNew = function () {
}
}
this.version = Date.now();
this.version = Date.now(); // for observer optimization
};
SpriteMorph.prototype.endWarp = function () {
@ -1921,7 +1935,12 @@ SpriteMorph.prototype.blockTemplates = function (category) {
blocks.push(block('getTimer'));
blocks.push('-');
blocks.push(block('reportAttributeOf'));
if (SpriteMorph.prototype.enableFirstClass) {
blocks.push(block('reportGet'));
}
blocks.push('-');
blocks.push(block('reportURL'));
blocks.push('-');
blocks.push(block('reportIsFastTracking'));
@ -2756,7 +2775,9 @@ SpriteMorph.prototype.userMenu = function () {
// menu.addItem('help', 'nop');
return menu;
}
menu.addItem("duplicate", 'duplicate');
if (!this.isClone) {
menu.addItem("duplicate", 'duplicate');
}
menu.addItem("delete", 'remove');
menu.addItem("move", 'moveCenter');
if (!this.isClone) {
@ -2814,12 +2835,30 @@ SpriteMorph.prototype.remove = function () {
}
};
// SpriteMorph cloning (experimental)
// SpriteMorph cloning
/*
clones are temporary, partially shallow copies of sprites that don't
appear as icons in the corral. Clones get deleted when the red stop button
is pressed. Shallow-copying clones' scripts and costumes makes spawning
very fast, so they can be used for particle system simulations.
This speed-up, however, comes at the cost of some detrimental side
effects: Changes to a costume or a script of the original sprite are
in some cases shared with all of its clones, however such shared changes
are hard to predict for users and not actively propagated, so they don't
offer any reliable feature, and will not be supported as such.
Changes to the original sprite's scripts affect all of its clones, unless
the script contains any custom block whose definition contains one or more
block variables (in which case the script does get deep-copied).
The original sprite's scripting area, costumes wardrobe or sounds jukebox
are also not shared. therefore adding or deleting a script, sound or
costume in the original sprite has no effect on any of its clones.
*/
SpriteMorph.prototype.createClone = function () {
var stage = this.parentThatIsA(StageMorph);
if (stage && stage.cloneCount <= 1000) {
this.fullCopy().clonify(stage);
if (stage && stage.cloneCount <= 2000) {
this.fullCopy(true).clonify(stage);
}
};
@ -2836,19 +2875,35 @@ SpriteMorph.prototype.clonify = function (stage) {
stage.add(this);
hats = this.allHatBlocksFor('__clone__init__');
hats.forEach(function (block) {
stage.threads.startProcess(block, stage.isThreadSafe);
stage.threads.startProcess(
block,
stage.isThreadSafe,
null, // export result
null, // callback
null, // is clicked
true // right away
);
});
this.endWarp();
};
SpriteMorph.prototype.removeClone = function () {
if (this.isClone) {
// this.stopTalking();
this.parent.threads.stopAllForReceiver(this);
this.corpsify();
this.destroy();
this.parent.cloneCount -= 1;
}
};
// SpriteMorph deleting
SpriteMorph.prototype.corpsify = function () {
this.isCorpse = true;
this.version = Date.now();
};
// SpriteMorph primitives
// SpriteMorph hiding and showing:
@ -3666,6 +3721,53 @@ SpriteMorph.prototype.bounceOffEdge = function () {
this.positionTalkBubble();
};
// SpriteMorph rotation center / fixation point manipulation
SpriteMorph.prototype.setRotationX = function (absoluteX) {
this.setRotationCenter(new Point(absoluteX, this.yPosition()));
};
SpriteMorph.prototype.setRotationY = function (absoluteY) {
this.setRotationCenter(new Point(this.xPosition(), absoluteY));
};
SpriteMorph.prototype.setRotationCenter = function (absoluteCoordinate) {
var delta, normal;
if (!this.costume) {
throw new Error('setting the rotation center requires a costume');
}
delta = absoluteCoordinate.subtract(
new Point(this.xPosition(), this.yPosition())
).divideBy(this.scale).rotateBy(radians(90 - this.heading));
normal = this.costume.rotationCenter.add(new Point(delta.x, -delta.y));
this.costume.rotationCenter = normal;
this.drawNew();
};
SpriteMorph.prototype.xCenter = function () {
var stage = this.parentThatIsA(StageMorph);
if (!stage && this.parent.grabOrigin) { // I'm currently being dragged
stage = this.parent.grabOrigin.origin;
}
if (stage) {
return (this.center().x - stage.center().x) / stage.scale;
}
return this.center().x;
};
SpriteMorph.prototype.yCenter = function () {
var stage = this.parentThatIsA(StageMorph);
if (!stage && this.parent.grabOrigin) { // I'm currently being dragged
stage = this.parent.grabOrigin.origin;
}
if (stage) {
return (stage.center().y - this.center().y) / stage.scale;
}
return this.center().y;
};
// SpriteMorph message broadcasting
SpriteMorph.prototype.allMessageNames = function () {
@ -4363,7 +4465,23 @@ SpriteMorph.prototype.thumbnail = function (extentPoint) {
trg = newCanvas(extentPoint),
ctx = trg.getContext('2d');
function xOut(style, alpha, width) {
var inset = Math.min(extentPoint.x, extentPoint.y) / 10;
ctx.strokeStyle = style;
ctx.globalAlpha = alpha;
ctx.compositeOperation = 'lighter';
ctx.lineWidth = width || 1;
ctx.moveTo(inset, inset);
ctx.lineTo(trg.width - inset, trg.height - inset);
ctx.moveTo(inset, trg.height - inset);
ctx.lineTo(trg.width - inset, inset);
ctx.stroke();
}
ctx.save();
if (this.isCorpse) {
ctx.globalAlpha = 0.3;
}
if (src.width && src.height) {
ctx.scale(scale, scale);
ctx.drawImage(
@ -4372,6 +4490,11 @@ SpriteMorph.prototype.thumbnail = function (extentPoint) {
Math.floor(yOffset / scale)
);
}
if (this.isCorpse) {
ctx.restore();
xOut('white', 0.8, 6);
xOut('black', 0.8, 1);
}
return trg;
};
@ -4709,7 +4832,6 @@ StageMorph.uber = FrameMorph.prototype;
// StageMorph preferences settings
StageMorph.prototype.dimensions = new Point(480, 360); // unscaled extent
StageMorph.prototype.frameRate = 0; // unscheduled per default
StageMorph.prototype.isCachingPrimitives
@ -4845,6 +4967,7 @@ StageMorph.prototype.drawNew = function () {
);
this.image = this.applyGraphicsEffects(this.image);
}
this.version = Date.now(); // for observer optimization
};
StageMorph.prototype.drawOn = function (aCanvas, aRect) {
@ -5256,7 +5379,7 @@ StageMorph.prototype.fireKeyEvent = function (key) {
return this.fireStopAllEvent();
}
this.children.concat(this).forEach(function (morph) {
if (morph instanceof SpriteMorph || morph instanceof StageMorph) {
if (isSnapObject(morph)) {
hats = hats.concat(morph.allHatBlocksForKey(evt));
}
});
@ -5284,7 +5407,7 @@ StageMorph.prototype.fireGreenFlagEvent = function () {
myself = this;
this.children.concat(this).forEach(function (morph) {
if (morph instanceof SpriteMorph || morph instanceof StageMorph) {
if (isSnapObject(morph)) {
hats = hats.concat(morph.allHatBlocksFor('__shout__go__'));
}
});
@ -5327,6 +5450,8 @@ StageMorph.prototype.removeAllClones = function () {
);
clones.forEach(function (clone) {
myself.threads.stopAllForReceiver(clone);
clone.detachFromAnchor();
clone.corpsify();
clone.destroy();
});
this.cloneCount = 0;
@ -5575,7 +5700,12 @@ StageMorph.prototype.blockTemplates = function (category) {
blocks.push(block('getTimer'));
blocks.push('-');
blocks.push(block('reportAttributeOf'));
if (SpriteMorph.prototype.enableFirstClass) {
blocks.push(block('reportGet'));
}
blocks.push('-');
blocks.push(block('reportURL'));
blocks.push('-');
blocks.push(block('reportIsFastTracking'));
@ -5848,9 +5978,16 @@ StageMorph.prototype.userMenu = function () {
StageMorph.prototype.showAll = function () {
var myself = this;
this.children.forEach(function (m) {
m.show();
m.keepWithin(myself);
if (m.fixLayout) {m.fixLayout(); }
if (m instanceof SpriteMorph) {
if (!m.anchor) {
m.show();
m.keepWithin(myself);
}
} else {
m.show();
m.keepWithin(myself);
if (m.fixLayout) {m.fixLayout(); }
}
});
};
@ -6173,14 +6310,31 @@ SpriteBubbleMorph.prototype.init = function (
SpriteBubbleMorph.prototype.dataAsMorph = function (data, toggle) {
var contents,
isTable,
sprite = SpriteMorph.prototype,
isText,
img,
scaledImg,
width;
if (data instanceof Morph) {
contents = data;
if (isSnapObject(data)) {
img = data.thumbnail(new Point(40, 40));
contents = new Morph();
contents.silentSetWidth(img.width);
contents.silentSetHeight(img.height);
contents.image = img;
contents.version = data.version;
contents.step = function () {
if (this.version !== data.version) {
img = data.thumbnail(new Point(40, 40));
this.image = img;
this.version = data.version;
this.changed();
}
};
} else {
contents = data;
}
} else if (isString(data)) {
isText = true;
contents = new TextMorph(
@ -6209,7 +6363,13 @@ SpriteBubbleMorph.prototype.dataAsMorph = function (data, toggle) {
contents.silentSetHeight(data.height);
contents.image = data;
} else if (data instanceof List) {
if (!toggle && data.isTable()) {
if (toggle && this.contentsMorph) {
isTable = (this.contentsMorph instanceof ListWatcherMorph);
} else {
isTable = data.isTable();
}
if (isTable) { // (!toggle && data.isTable()) {
contents = new TableFrameMorph(new TableMorph(data, 10));
if (this.stage) {
contents.expand(this.stage.extent().translateBy(
@ -6495,7 +6655,6 @@ Costume.prototype.copy = function () {
var canvas = newCanvas(this.extent()),
cpy,
ctx;
ctx = canvas.getContext('2d');
ctx.drawImage(this.contents, 0, 0);
cpy = new Costume(canvas, this.name ? copy(this.name) : null);
@ -6540,7 +6699,7 @@ Costume.prototype.edit = function (aWorld, anIDE, isnew, oncancel, onsubmit) {
newCanvas(StageMorph.prototype.dimensions) :
this.contents,
isnew ?
new Point(240, 180) :
null :
this.rotationCenter,
function (img, rc) {
myself.contents = img;
@ -6963,6 +7122,7 @@ CellMorph.prototype.init = function (contents, color, idx, parentCell) {
);
this.color = color || new Color(255, 140, 0);
this.isBig = false;
this.version = null; // only for observing sprites
this.drawNew();
};
@ -7012,6 +7172,16 @@ CellMorph.prototype.fixLayout = function () {
// CellMorph drawing:
CellMorph.prototype.update = function () {
// special case for observing sprites
if (!isSnapObject(this.contents)) {
return;
}
if (this.version !== this.contents.version) {
this.drawNew();
}
};
CellMorph.prototype.drawNew = function (toggle, type) {
var context,
txt,
@ -7029,11 +7199,21 @@ CellMorph.prototype.drawNew = function (toggle, type) {
// re-build my contents
if (toggle || (this.contentsMorph && !isSameList && !isSameTable)) {
this.contentsMorph.destroy();
this.version = null;
}
if (toggle || (!isSameList && !isSameTable)) {
if (this.contents instanceof Morph) {
this.contentsMorph = this.contents;
if (isSnapObject(this.contents)) {
img = this.contents.thumbnail(new Point(40, 40));
this.contentsMorph = new Morph();
this.contentsMorph.silentSetWidth(img.width);
this.contentsMorph.silentSetHeight(img.height);
this.contentsMorph.image = img;
this.version = this.contents.version;
} else {
this.contentsMorph = this.contents;
}
} else if (isString(this.contents)) {
txt = this.contents.length > 500 ?
this.contents.slice(0, 500) + '...' : this.contents;
@ -7444,6 +7624,8 @@ WatcherMorph.prototype.update = function () {
}
if (this.cellMorph.contentsMorph instanceof ListWatcherMorph) {
this.cellMorph.contentsMorph.update();
} else if (isSnapObject(this.cellMorph.contents)) {
this.cellMorph.update();
}
};

Wyświetl plik

@ -61,19 +61,18 @@
Oct 02 - revert disable smoothing (Jens)
Dec 15 - center rotation point on costume creating (Craxic)
Jan 18 - avoid pixel collision detection in PaintCanvas (Jens)
*/
Mar 22 - fixed automatic rotation center point mechanism (Jens)
*/
/*global Point, Rectangle, DialogBoxMorph, fontHeight, AlignmentMorph,
FrameMorph, PushButtonMorph, Color, SymbolMorph, newCanvas, Morph, TextMorph,
CostumeIconMorph, IDE_Morph, Costume, SpriteMorph, nop, Image, WardrobeMorph,
TurtleIconMorph, localize, MenuMorph, InputFieldMorph, SliderMorph,
ToggleMorph, ToggleButtonMorph, BoxMorph, modules, radians,
MorphicPreferences, getDocumentPositionOf, StageMorph
*/
/*global Point, Rectangle, DialogBoxMorph, AlignmentMorph, PushButtonMorph,
Color, SymbolMorph, newCanvas, Morph, TextMorph, Costume, SpriteMorph, nop,
localize, InputFieldMorph, SliderMorph, ToggleMorph, ToggleButtonMorph,
BoxMorph, modules, radians, MorphicPreferences, getDocumentPositionOf,
StageMorph, isNil*/
// Global stuff ////////////////////////////////////////////////////////
modules.paint = '2016-January-18';
modules.paint = '2016-May-02';
// Declarations
@ -253,7 +252,6 @@ PaintEditorMorph.prototype.buildScaleBox = function () {
PaintEditorMorph.prototype.openIn = function (world, oldim, oldrc, callback) {
// Open the editor in a world with an optional image to edit
this.oldim = oldim;
this.oldrc = oldrc.copy();
this.callback = callback || nop;
this.processKeyUp = function () {
@ -268,9 +266,10 @@ PaintEditorMorph.prototype.openIn = function (world, oldim, oldrc, callback) {
//merge oldim:
if (this.oldim) {
this.paper.automaticCrosshairs = isNil(oldrc);
this.paper.centermerge(this.oldim, this.paper.paper);
this.paper.rotationCenter =
this.oldrc.add(
(oldrc || new Point(0, 0)).add(
new Point(
(this.paper.paper.width - this.oldim.width) / 2,
(this.paper.paper.height - this.oldim.height) / 2

Wyświetl plik

@ -56,11 +56,11 @@ Color, List, newCanvas, Costume, Sound, Audio, IDE_Morph, ScriptsMorph,
BlockMorph, ArgMorph, InputSlotMorph, TemplateSlotMorph, CommandSlotMorph,
FunctionSlotMorph, MultiArgMorph, ColorSlotMorph, nop, CommentMorph, isNil,
localize, sizeOf, ArgLabelMorph, SVG_Costume, MorphicPreferences,
SyntaxElementMorph, Variable*/
SyntaxElementMorph, Variable, isSnapObject, console*/
// Global stuff ////////////////////////////////////////////////////////
modules.store = '2016-March-16';
modules.store = '2016-May-02';
// XML_Serializer ///////////////////////////////////////////////////////
@ -974,7 +974,16 @@ SnapSerializer.prototype.loadScript = function (model) {
return;
}
if (block) {
block.nextBlock(nextBlock);
if (block.nextBlock && (nextBlock instanceof CommandBlockMorph)) {
block.nextBlock(nextBlock);
} else { // +++
console.log(
'SNAP: expecting a command but getting a reporter:\n' +
' ' + block.blockSpec + '\n' +
' ' + nextBlock.blockSpec
);
return topBlock;
}
} else {
topBlock = nextBlock;
}
@ -1605,10 +1614,14 @@ VariableFrame.prototype.toXML = function (serializer) {
dta = serializer.format(
'<variable name="@">%</variable>',
v,
typeof val === 'object' ? serializer.store(val)
: typeof val === 'boolean' ?
serializer.format('<bool>$</bool>', val)
: serializer.format('<l>$</l>', val)
typeof val === 'object' ?
(isSnapObject(val) ? ''
: serializer.store(val))
: typeof val === 'boolean' ?
serializer.format(
'<bool>$</bool>', val
)
: serializer.format('<l>$</l>', val)
);
}
return vars + dta;
@ -1897,7 +1910,8 @@ List.prototype.toXML = function (serializer, mediaContext) {
xml += serializer.format(
'<item>%</item>',
typeof value === 'object' ?
serializer.store(value, mediaContext)
(isSnapObject(value) ? ''
: serializer.store(value, mediaContext))
: typeof value === 'boolean' ?
serializer.format('<bool>$</bool>', value)
: serializer.format('<l>$</l>', value)
@ -1916,7 +1930,8 @@ List.prototype.toXML = function (serializer, mediaContext) {
xml += serializer.format(
'<item>%</item>',
typeof value === 'object' ?
serializer.store(value, mediaContext)
(isSnapObject(value) ? ''
: serializer.store(value, mediaContext))
: typeof value === 'boolean' ?
serializer.format('<bool>$</bool>', value)
: serializer.format('<l>$</l>', value)
@ -1933,7 +1948,8 @@ List.prototype.toXML = function (serializer, mediaContext) {
return xml + serializer.format(
'<item>%</item>',
typeof item === 'object' ?
serializer.store(item, mediaContext)
(isSnapObject(item) ? ''
: serializer.store(item, mediaContext))
: typeof item === 'boolean' ?
serializer.format('<bool>$</bool>', item)
: serializer.format('<l>$</l>', item)

Wyświetl plik

@ -68,9 +68,9 @@
MorphicPreferences, FrameMorph, HandleMorph, DialogBoxMorph, isString,
SpriteMorph, Context, Costume, ArgMorph, BlockEditorMorph,
SyntaxElementMorph, MenuMorph, SpriteBubbleMorph, SpeechBubbleMorph,
CellMorph, ListWatcherMorph, isNil, BoxMorph, Variable*/
CellMorph, ListWatcherMorph, isNil, BoxMorph, Variable, isSnapObject*/
modules.tables = '2016-February-24';
modules.tables = '2016-May-02';
var Table;
var TableCellMorph;
@ -307,6 +307,10 @@ TableCellMorph.prototype.setData = function (data, extent) {
// note: don't call changed(), let the TableMorph handle it instead
};
TableCellMorph.prototype.getData = function () {
return this.data instanceof Array ? this.data[0] : this.data;
};
TableCellMorph.prototype.drawNew = function () {
this.image = newCanvas(this.extent());
this.drawData();
@ -373,7 +377,11 @@ TableCellMorph.prototype.drawData = function (lbl, bg) {
TableCellMorph.prototype.dataRepresentation = function (dta) {
if (dta instanceof Morph) {
return dta.fullImageClassic();
if (isSnapObject(dta)) {
return dta.thumbnail(new Point(40, 40));
} else {
return dta.fullImageClassic();
}
} else if (isString(dta)) {
return dta.length > 100 ? dta.slice(0, 100) + '...' : dta;
} else if (typeof dta === 'number') {
@ -544,6 +552,9 @@ TableMorph.prototype.init = function (
this.resizeCol = null;
this.resizeRow = null;
// cached property for updating (don not persist):
this.wantsUpdate = false;
// initialize inherited properties:
// make sure not to draw anything just yet
// therefore omit FrameMorph's properties (not needed here)
@ -697,6 +708,9 @@ TableMorph.prototype.buildCells = function () {
).add(pos)
);
this.add(cell);
if (isSnapObject(cell.getData())) {
this.wantsUpdate = true;
}
}
}
this.add(this.hBar);
@ -718,6 +732,9 @@ TableMorph.prototype.drawData = function (noScrollUpdate) {
!r ? r : r + this.startRow - 1
)
);
if (isSnapObject(cell.getData())) {
this.wantsUpdate = true;
}
}
}
if (!noScrollUpdate) {this.updateScrollBars(); }
@ -777,7 +794,10 @@ TableMorph.prototype.update = function () {
version = this.table instanceof List ?
this.table.version(this.startRow, this.rows)
: this.table.lastChanged;
if (this.tableVersion === version) { return; }
if (this.tableVersion === version && !this.wantsUpdate) {
return;
}
this.wantsUpdate = false;
if (this.table instanceof List) {
oldCols = this.columns.length;
oldRows = this.rows;
@ -1048,6 +1068,7 @@ TableMorph.prototype.showListView = function () {
view.drawNew(true);
} else if (view instanceof SpeechBubbleMorph) {
view.contents = new ListWatcherMorph(this.table);
view.contents.step = view.contents.update;
view.contents.expand(this.extent());
view.drawNew(true);
} else { // watcher cell

Wyświetl plik

@ -59,9 +59,9 @@ degrees, detect, nop, radians, ReporterSlotMorph, CSlotMorph, RingMorph,
IDE_Morph, ArgLabelMorph, localize, XML_Element, hex_sha512, TableDialogMorph,
StageMorph, SpriteMorph, StagePrompterMorph, Note, modules, isString, copy,
isNil, WatcherMorph, List, ListWatcherMorph, alert, console, TableMorph,
TableFrameMorph*/
TableFrameMorph, isSnapObject*/
modules.threads = '2016-March-16';
modules.threads = '2016-May-04';
var ThreadManager;
var Process;
@ -191,7 +191,8 @@ ThreadManager.prototype.startProcess = function (
isThreadSafe,
exportResult,
callback,
isClicked
isClicked,
rightAway
) {
var active = this.findProcess(block),
top = block.topBlock(),
@ -203,13 +204,16 @@ ThreadManager.prototype.startProcess = function (
active.stop();
this.removeTerminatedProcesses();
}
newProc = new Process(block.topBlock(), callback);
newProc = new Process(block.topBlock(), callback, rightAway);
newProc.exportResult = exportResult;
newProc.isClicked = isClicked || false;
if (!newProc.homeContext.receiver.isClone) {
top.addHighlight();
}
this.processes.push(newProc);
if (rightAway) {
newProc.runStep();
}
return newProc;
};
@ -350,8 +354,8 @@ ThreadManager.prototype.doWhen = function (block, stopIt) {
if (invoke(
pred,
null,
null,
20,
block.receiver(), // needed for shallow copied clones - was null
50,
'the predicate takes\ntoo long for a\ncustom hat block',
true // suppress errors => handle them right here instead
) === true) {
@ -430,8 +434,9 @@ Process.prototype = {};
Process.prototype.constructor = Process;
Process.prototype.timeout = 500; // msecs after which to force yield
Process.prototype.isCatchingErrors = true;
Process.prototype.enableLiveCoding = false; // experimental
function Process(topBlock, onComplete) {
function Process(topBlock, onComplete, rightAway) {
this.topBlock = topBlock || null;
this.readyToYield = false;
@ -462,7 +467,9 @@ function Process(topBlock, onComplete) {
topBlock.blockSequence(),
this.homeContext
);
this.pushContext('doYield'); // highlight top block
if (!rightAway) {
this.pushContext('doYield'); // highlight top block
}
}
}
@ -485,8 +492,9 @@ Process.prototype.runStep = function (deadline) {
this.readyToYield = false;
while (!this.readyToYield
&& this.context
&& (this.isAtomic ?
(Date.now() - this.lastYield < this.timeout) : true)
&& // (this.isAtomic ?
(Date.now() - this.lastYield < this.timeout)
// : true)
) {
// also allow pausing inside atomic steps - for PAUSE block primitive:
if (this.isPaused) {
@ -870,7 +878,8 @@ Process.prototype.reify = function (topBlock, parameterNames, isCustomBlock) {
i = 0;
if (topBlock) {
context.expression = topBlock.fullCopy();
context.expression = this.enableLiveCoding ?
topBlock : topBlock.fullCopy();
context.expression.show(); // be sure to make visible if in app mode
if (!isCustomBlock) {
@ -888,7 +897,8 @@ Process.prototype.reify = function (topBlock, parameterNames, isCustomBlock) {
}
} else {
context.expression = [this.context.expression.fullCopy()];
context.expression = this.enableLiveCoding ? [this.context.expression]
: [this.context.expression.fullCopy()];
}
context.inputs = parameterNames.asArray();
@ -1294,16 +1304,20 @@ Process.prototype.doDeclareVariables = function (varNames) {
Process.prototype.doSetVar = function (varName, value) {
var varFrame = this.context.variables,
name = varName;
name = varName,
rcvr;
if (name instanceof Context) {
rcvr = this.blockReceiver();
if (name.expression.selector === 'reportGetVar') {
name.variables.setVar(
name.expression.blockSpec,
value,
this.blockReceiver()
rcvr
);
return;
}
this.doSet(name, value);
return;
}
varFrame.setVar(name, value, this.blockReceiver());
};
@ -1959,7 +1973,7 @@ Process.prototype.blockReceiver = function () {
// Process sound primitives (interpolated)
Process.prototype.doPlaySoundUntilDone = function (name) {
var sprite = this.homeContext.receiver;
var sprite = this.blockReceiver();
if (this.context.activeAudio === null) {
this.context.activeAudio = sprite.playSound(name);
}
@ -2060,7 +2074,7 @@ Process.prototype.doBroadcast = function (message) {
if (message !== '') {
stage.lastMessage = message;
stage.children.concat(stage).forEach(function (morph) {
if (morph instanceof SpriteMorph || morph instanceof StageMorph) {
if (isSnapObject(morph)) {
hats = hats.concat(morph.allHatBlocksFor(message));
}
});
@ -2116,6 +2130,12 @@ Process.prototype.assertType = function (thing, typeString) {
throw new Error('expecting ' + typeString + ' but getting ' + thingType);
};
Process.prototype.assertAlive = function (thing) {
if (thing && thing.isCorpse) {
throw new Error('cannot operate on a deleted sprite');
}
};
Process.prototype.reportTypeOf = function (thing) {
// answer a string denoting the argument's type
var exp;
@ -2134,6 +2154,12 @@ Process.prototype.reportTypeOf = function (thing) {
if (thing instanceof List) {
return 'list';
}
if (thing instanceof SpriteMorph) {
return 'sprite';
}
if (thing instanceof StageMorph) {
return 'stage';
}
if (thing instanceof Context) {
if (thing.expression instanceof RingMorph) {
return thing.expression.dataType();
@ -2473,6 +2499,11 @@ Process.prototype.getOtherObject = function (name, thisObj, stageObj) {
// private, find the sprite indicated by the given name
// either onstage or in the World's hand
// experimental: deal with first-class sprites
if (isSnapObject(name)) {
return name;
}
var stage = isNil(stageObj) ?
thisObj.parentThatIsA(StageMorph) : stageObj,
thatObj = null;
@ -2564,7 +2595,7 @@ Process.prototype.doGotoObject = function (name) {
// Process temporary cloning (Scratch-style)
Process.prototype.createClone = function (name) {
var thisObj = this.homeContext.receiver,
var thisObj = this.blockReceiver(),
thatObj;
if (!name) {return; }
@ -2623,7 +2654,14 @@ Process.prototype.objectTouchingObject = function (thisObj, name) {
thisObj.isTouching(stage.penTrailsMorph())) {
return true;
}
those = this.getObjectsNamed(name, thisObj, stage); // clones
if (isSnapObject(name)) {
return thisObj.isTouching(name);
}
if (name instanceof List) { // assume all elements to be sprites
those = name.itemsArray();
} else {
those = this.getObjectsNamed(name, thisObj, stage); // clones
}
if (those.some(function (any) {
return thisObj.isTouching(any);
})) {
@ -2640,7 +2678,7 @@ Process.prototype.objectTouchingObject = function (thisObj, name) {
Process.prototype.reportTouchingColor = function (aColor) {
// also check for any parts (subsprites)
var thisObj = this.homeContext.receiver,
var thisObj = this.blockReceiver(),
stage;
if (thisObj) {
@ -2661,7 +2699,7 @@ Process.prototype.reportTouchingColor = function (aColor) {
Process.prototype.reportColorIsTouchingColor = function (color1, color2) {
// also check for any parts (subsprites)
var thisObj = this.homeContext.receiver,
var thisObj = this.blockReceiver(),
stage;
if (thisObj) {
@ -2713,6 +2751,7 @@ Process.prototype.reportAttributeOf = function (attribute, name) {
stage;
if (thisObj) {
this.assertAlive(thisObj);
stage = thisObj.parentThatIsA(StageMorph);
if (stage.name === name) {
thatObj = stage;
@ -2720,6 +2759,7 @@ Process.prototype.reportAttributeOf = function (attribute, name) {
thatObj = this.getOtherObject(name, thisObj, stage);
}
if (thatObj) {
this.assertAlive(thatObj);
if (attribute instanceof Context) {
return this.reportContextFor(attribute, thatObj);
}
@ -2747,6 +2787,139 @@ Process.prototype.reportAttributeOf = function (attribute, name) {
return '';
};
Process.prototype.reportGet = function (query) {
// experimental, answer a reference to a first-class member
// or a list of first-class members
var thisObj = this.blockReceiver(),
neighborhood,
stage,
objName;
if (thisObj) {
switch (this.inputOption(query)) {
case 'self' :
return thisObj;
case 'other sprites':
stage = thisObj.parentThatIsA(StageMorph);
return new List(
stage.children.filter(function (each) {
return each instanceof SpriteMorph &&
each !== thisObj;
})
);
case 'parts':
return new List(thisObj.parts || []);
case 'anchor':
return thisObj.anchor || '';
case 'parent':
return thisObj.exemplar || '';
case 'children':
return new List(thisObj.specimens ? thisObj.specimens() : []);
case 'clones':
stage = thisObj.parentThatIsA(StageMorph);
objName = thisObj.name || thisObj.cloneOriginName;
return new List(
stage.children.filter(function (each) {
return each.isClone &&
(each !== thisObj) &&
(each.cloneOriginName === objName);
})
);
case 'other clones':
return thisObj.isClone ? this.reportGet(['clones']) : new List();
case 'neighbors':
stage = thisObj.parentThatIsA(StageMorph);
neighborhood = thisObj.bounds.expandBy(new Point(
thisObj.width(),
thisObj.height()
));
return new List(
stage.children.filter(function (each) {
return each instanceof SpriteMorph &&
(each !== thisObj) &&
each.bounds.intersects(neighborhood);
})
);
case 'dangling?':
return !thisObj.rotatesWithAnchor;
case 'rotation x':
return thisObj.xPosition();
case 'rotation y':
return thisObj.yPosition();
case 'center x':
return thisObj.xCenter();
case 'center y':
return thisObj.yCenter();
case 'name':
return thisObj.name;
case 'stage':
return thisObj.parentThatIsA(StageMorph);
}
}
return '';
};
Process.prototype.doSet = function (attribute, value) {
// experimental, manipulate sprites' attributes
var name, rcvr;
if (!(attribute instanceof Context)) {
return;
}
rcvr = this.blockReceiver();
this.assertAlive(rcvr);
if (!(attribute instanceof Context) ||
attribute.expression.selector !== 'reportGet') {
throw new Error(localize('unsupported attribute'));
}
name = attribute.expression.inputs()[0].evaluate();
if (name instanceof Array) {
name = name[0];
}
switch (name) {
case 'anchor':
this.assertType(rcvr, 'sprite');
if (value instanceof SpriteMorph) {
// avoid circularity here, because the GUI already checks for
// conflicts while the user drags parts over prospective targets
if (!rcvr.enableNesting || contains(rcvr.allParts(), value)) {
throw new Error(
localize('unable to nest\n(disabled or circular?)')
);
}
value.attachPart(rcvr);
} else {
rcvr.detachFromAnchor();
}
break;
case 'parent':
this.assertType(rcvr, 'sprite');
value = value instanceof SpriteMorph ? value : null;
// needed: circularity avoidance
rcvr.setExemplar(value);
break;
case 'dangling?':
this.assertType(rcvr, 'sprite');
this.assertType(value, 'Boolean');
rcvr.rotatesWithAnchor = !value;
rcvr.version = Date.now();
break;
case 'rotation x':
this.assertType(rcvr, 'sprite');
this.assertType(value, 'number');
rcvr.setRotationX(value);
break;
case 'rotation y':
this.assertType(rcvr, 'sprite');
this.assertType(value, 'number');
rcvr.setRotationY(value);
break;
default:
throw new Error(
'"' + localize(name) + '" ' + localize('is read-only')
);
}
};
Process.prototype.reportContextFor = function (context, otherObj) {
// Private - return a copy of the context
// and bind it to another receiver

Wyświetl plik

@ -74,7 +74,7 @@ HTMLCanvasElement, fontHeight, SymbolMorph, localize, SpeechBubbleMorph,
ArrowMorph, MenuMorph, isString, isNil, SliderMorph, MorphicPreferences,
ScrollFrameMorph*/
modules.widgets = '2015-July-27';
modules.widgets = '2016-May-02';
var PushButtonMorph;
var ToggleButtonMorph;
@ -2513,6 +2513,12 @@ DialogBoxMorph.prototype.fixLayout = function () {
+ this.buttons.height()
+ this.padding
);
this.silentSetWidth(Math.max(
this.width(),
this.buttons.width()
+ (2 * this.padding)
)
);
this.buttons.setCenter(this.center());
this.buttons.setBottom(this.bottom() - this.padding);
}
@ -2927,6 +2933,7 @@ AlignmentMorph.prototype.fixLayout = function () {
))
);
}
cfb = c.fullBounds();
newBounds = newBounds.merge(cfb);
} else {
newBounds = cfb;