Merge branch 'manual-chapter2' into manual-chapter3

dev
Bartosz Leper 2015-08-02 20:15:47 +02:00
commit c04698ea26
21 zmienionych plików z 5170 dodań i 291 usunięć

969
blocks.js

Plik diff jest za duży Load Diff

17
byob.js
Wyświetl plik

@ -102,11 +102,11 @@ ArrowMorph, PushButtonMorph, contains, InputSlotMorph, ShadowMorph,
ToggleButtonMorph, IDE_Morph, MenuMorph, copy, ToggleElementMorph,
Morph, fontHeight, StageMorph, SyntaxElementMorph, SnapSerializer,
CommentMorph, localize, CSlotMorph, SpeechBubbleMorph, MorphicPreferences,
SymbolMorph, isNil*/
SymbolMorph, isNil, CursorMorph*/
// Global stuff ////////////////////////////////////////////////////////
modules.byob = '2015-June-25';
modules.byob = '2015-July-28';
// Declarations
@ -1727,8 +1727,9 @@ BlockEditorMorph.prototype.popUp = function () {
// BlockEditorMorph ops
BlockEditorMorph.prototype.accept = function () {
BlockEditorMorph.prototype.accept = function (origin) {
// check DialogBoxMorph comment for accept()
if (origin instanceof CursorMorph) {return; }
if (this.action) {
if (typeof this.target === 'function') {
if (typeof this.action === 'function') {
@ -1747,7 +1748,8 @@ BlockEditorMorph.prototype.accept = function () {
this.close();
};
BlockEditorMorph.prototype.cancel = function () {
BlockEditorMorph.prototype.cancel = function (origin) {
if (origin instanceof CursorMorph) {return; }
//this.refreshAllBlockInstances();
this.close();
};
@ -1966,8 +1968,13 @@ PrototypeHatBlockMorph.prototype.init = function (definition) {
PrototypeHatBlockMorph.prototype.mouseClickLeft = function () {
// relay the mouse click to my prototype block to
// pop-up a Block Dialog
// pop-up a Block Dialog, unless the shift key
// is pressed, in which case initiate keyboard
// editing support
if (this.world().currentKey === 16) { // shift-clicked
return this.focus();
}
this.children[0].mouseClickLeft();
};

349
gui.js
Wyświetl plik

@ -43,6 +43,7 @@
TurtleIconMorph
CostumeIconMorph
WardrobeMorph
StageHandleMorph;
credits
@ -65,11 +66,11 @@ ScriptsMorph, isNil, SymbolMorph, BlockExportDialogMorph,
BlockImportDialogMorph, SnapTranslator, localize, List, InputSlotMorph,
SnapCloud, Uint8Array, HandleMorph, SVG_Costume, fontHeight, hex_sha512,
sb, CommentMorph, CommandBlockMorph, BlockLabelPlaceHolderMorph, Audio,
SpeechBubbleMorph*/
SpeechBubbleMorph, ScriptFocusMorph*/
// Global stuff ////////////////////////////////////////////////////////
modules.gui = '2015-June-25';
modules.gui = '2015-July-28';
// Declarations
@ -81,11 +82,18 @@ var TurtleIconMorph;
var WardrobeMorph;
var SoundIconMorph;
var JukeboxMorph;
var StageHandleMorph;
// Get the full url without "snap.html"
var baseUrl = document.URL.split('/');
baseUrl.pop(baseUrl.length - 1);
baseUrl = baseUrl.join('/') + '/';
var baseURL = (function getPath(location) {
var origin, path, slash;
path = location.pathname; // starts with a /
origin = location.origin; // has no trailing /
slash = path.lastIndexOf('/');
path = path.slice(0, slash + 1); // keep a trailing /
return origin + path;
}(window.location));
// IDE_Morph ///////////////////////////////////////////////////////////
@ -230,6 +238,7 @@ IDE_Morph.prototype.init = function (isAutoFill) {
this.spriteBar = null;
this.spriteEditor = null;
this.stage = null;
this.stageHandle = null;
this.corralBar = null;
this.corral = null;
@ -975,9 +984,7 @@ IDE_Morph.prototype.createPalette = function (forSearching) {
IDE_Morph.prototype.createStage = function () {
// assumes that the logo pane has already been created
if (this.stage) {
this.stage.destroy();
}
if (this.stage) {this.stage.destroy(); }
StageMorph.prototype.frameRate = 0;
this.stage = new StageMorph(this.globalVariables);
this.stage.setExtent(this.stage.dimensions); // dimensions are fixed
@ -992,6 +999,13 @@ IDE_Morph.prototype.createStage = function () {
this.add(this.stage);
};
IDE_Morph.prototype.createStageHandle = function () {
// assumes that the stage has already been created
if (this.stageHandle) {this.stageHandle.destroy(); }
this.stageHandle = new StageHandleMorph(this.stage);
this.add(this.stageHandle);
};
IDE_Morph.prototype.createSpriteBar = function () {
// assumes that the categories pane has already been created
var rotationStyleButtons = [],
@ -1355,6 +1369,7 @@ IDE_Morph.prototype.createCorral = function () {
// assumes the corral bar has already been created
var frame, template, padding = 5, myself = this;
this.createStageHandle();
if (this.corral) {
this.corral.destroy();
}
@ -1486,10 +1501,10 @@ IDE_Morph.prototype.fixLayout = function (situation) {
) * 10) / 10);
this.stage.setCenter(this.center());
} else {
// this.stage.setScale(this.isSmallStage ? 0.5 : 1);
this.stage.setScale(this.isSmallStage ? this.stageRatio : 1);
this.stage.setTop(this.logo.bottom() + padding);
this.stage.setRight(this.right());
this.stageHandle.fixLayout();
}
// spriteBar
@ -1538,7 +1553,12 @@ IDE_Morph.prototype.setProjectName = function (string) {
IDE_Morph.prototype.setExtent = function (point) {
var padding = new Point(430, 110),
minExt,
ext;
ext,
maxWidth,
minWidth,
maxHeight,
minRatio,
maxRatio;
// determine the minimum dimensions making sense for the current mode
if (this.isAppMode) {
@ -1546,21 +1566,29 @@ IDE_Morph.prototype.setExtent = function (point) {
this.controlBar.height() + 10
);
} else {
/* // auto-switches to small stage mode, commented out b/c I don't like it
if (point.x < 910) {
this.isSmallStage = true;
this.stageRatio = 0.5;
if (this.stageRatio > 1) {
minExt = padding.add(StageMorph.prototype.dimensions);
} else {
minExt = padding.add(
StageMorph.prototype.dimensions.multiplyBy(this.stageRatio)
);
}
*/
minExt = this.isSmallStage ?
padding.add(StageMorph.prototype.dimensions.divideBy(2))
: padding.add(StageMorph.prototype.dimensions);
/*
minExt = this.isSmallStage ?
new Point(700, 350) : new Point(910, 490);
*/
}
ext = point.max(minExt);
// adjust stage ratio if necessary
maxWidth = ext.x - (this.spriteBar.tabBar.fullBounds().right() -
this.left());
minWidth = SpriteIconMorph.prototype.thumbSize.x * 3;
maxHeight = (ext.y - SpriteIconMorph.prototype.thumbSize.y * 3.5);
minRatio = minWidth / this.stage.dimensions.x;
maxRatio = Math.min(
(maxWidth / this.stage.dimensions.x),
(maxHeight / this.stage.dimensions.y)
);
this.stageRatio = Math.min(maxRatio, Math.max(minRatio, this.stageRatio));
// apply
IDE_Morph.uber.setExtent.call(this, ext);
this.fixLayout();
};
@ -1746,6 +1774,9 @@ IDE_Morph.prototype.stopAllScripts = function () {
};
IDE_Morph.prototype.selectSprite = function (sprite) {
if (this.currentSprite && this.currentSprite.scripts.focus) {
this.currentSprite.scripts.focus.stopEditing();
}
this.currentSprite = sprite;
this.createPalette();
this.createSpriteBar();
@ -1800,7 +1831,8 @@ IDE_Morph.prototype.applySavedSettings = function () {
click = this.getSetting('click'),
longform = this.getSetting('longform'),
longurls = this.getSetting('longurls'),
plainprototype = this.getSetting('plainprototype');
plainprototype = this.getSetting('plainprototype'),
keyboard = this.getSetting('keyboard');
// design
if (design === 'flat') {
@ -1840,6 +1872,13 @@ IDE_Morph.prototype.applySavedSettings = function () {
this.projectsInURLs = false;
}
// keyboard editing
if (keyboard) {
ScriptsMorph.prototype.enableKeyboard = true;
} else {
ScriptsMorph.prototype.enableKeyboard = false;
}
// plain prototype labels
if (plainprototype) {
BlockLabelPlaceHolderMorph.prototype.plainLabel = true;
@ -2346,6 +2385,22 @@ IDE_Morph.prototype.settingsMenu = function () {
'check to enable\nsprite composition',
true
);
addPreference(
'Keyboard Editing',
function () {
ScriptsMorph.prototype.enableKeyboard =
!ScriptsMorph.prototype.enableKeyboard;
if (ScriptsMorph.prototype.enableKeyboard) {
myself.saveSetting('keyboard', true);
} else {
myself.removeSetting('keyboard');
}
},
ScriptsMorph.prototype.enableKeyboard,
'uncheck to disable\nkeyboard editing support',
'check to enable\nkeyboard editing support',
false
);
menu.addLine(); // everything below this line is stored in the project
addPreference(
'Thread safe scripts',
@ -2385,6 +2440,20 @@ IDE_Morph.prototype.settingsMenu = function () {
'check for block\nto text mapping features',
false
);
addPreference(
'Inheritance support',
function () {
StageMorph.prototype.enableInheritance =
!StageMorph.prototype.enableInheritance;
myself.currentSprite.blocksCache.variables = null;
myself.currentSprite.paletteCache.variables = null;
myself.refreshPalette();
},
StageMorph.prototype.enableInheritance,
'uncheck to disable\nsprite inheritance features',
'check for sprite\ninheritance features',
false
);
menu.popup(world, pos);
};
@ -2497,10 +2566,10 @@ IDE_Morph.prototype.projectMenu = function () {
function () {
// read a list of libraries from an external file,
var libMenu = new MenuMorph(this, 'Import library'),
libUrl = baseUrl + 'libraries/' + 'LIBRARIES';
libUrl = baseURL + 'libraries/' + 'LIBRARIES';
function loadLib(name) {
var url = baseUrl + 'libraries/' + name + '.xml';
var url = baseURL + 'libraries/' + name + '.xml';
myself.droppedText(myself.getURL(url), name);
}
@ -2617,7 +2686,7 @@ IDE_Morph.prototype.aboutSnap = function () {
module, btn1, btn2, btn3, btn4, licenseBtn, translatorsBtn,
world = this.world();
aboutTxt = 'Snap! 4.0.1\nBuild Your Own Blocks\n\n'
aboutTxt = 'Snap! 4.0.2\nBuild Your Own Blocks\n\n'
+ 'Copyright \u24B8 2015 Jens M\u00F6nig and '
+ 'Brian Harvey\n'
+ 'jens@moenig.org, bh@cs.berkeley.edu\n\n'
@ -2834,6 +2903,7 @@ IDE_Morph.prototype.newProject = function () {
StageMorph.prototype.codeMappings = {};
StageMorph.prototype.codeHeaders = {};
StageMorph.prototype.enableCodeMapping = false;
StageMorph.prototype.enableInheritance = false;
SpriteMorph.prototype.useFlatLineEnds = false;
this.setProjectName('');
this.projectNotes = '';
@ -3053,6 +3123,7 @@ IDE_Morph.prototype.rawOpenProjectString = function (str) {
StageMorph.prototype.codeMappings = {};
StageMorph.prototype.codeHeaders = {};
StageMorph.prototype.enableCodeMapping = false;
StageMorph.prototype.enableInheritance = false;
if (Process.prototype.isCatchingErrors) {
try {
this.serializer.openProject(
@ -3094,6 +3165,7 @@ IDE_Morph.prototype.rawOpenCloudDataString = function (str) {
StageMorph.prototype.codeMappings = {};
StageMorph.prototype.codeHeaders = {};
StageMorph.prototype.enableCodeMapping = false;
StageMorph.prototype.enableInheritance = false;
if (Process.prototype.isCatchingErrors) {
try {
model = this.serializer.parse(str);
@ -3417,6 +3489,7 @@ IDE_Morph.prototype.toggleAppMode = function (appMode) {
this.controlBar.projectButton,
this.controlBar.settingsButton,
this.controlBar.stageSizeButton,
this.stageHandle,
this.corral,
this.corralBar,
this.spriteEditor,
@ -3440,6 +3513,9 @@ IDE_Morph.prototype.toggleAppMode = function (appMode) {
morph.hide();
}
});
if (world.keyboardReceiver instanceof ScriptFocusMorph) {
world.keyboardReceiver.stopEditing();
}
} else {
this.setColor(this.backgroundColor);
this.controlBar.setColor(this.frameColor);
@ -3476,36 +3552,32 @@ IDE_Morph.prototype.toggleStageSize = function (isSmall) {
var myself = this,
smallRatio = 0.5,
world = this.world(),
shiftClicked = (world.currentKey === 16);
shiftClicked = (world.currentKey === 16),
altClicked = (world.currentKey === 18);
function toggle() {
myself.isSmallStage = isNil(isSmall) ? !myself.isSmallStage : isSmall;
}
function zoomIn() {
myself.step = function () {
myself.stageRatio -= (myself.stageRatio - smallRatio) / 2;
myself.setExtent(world.extent());
if (myself.stageRatio < (smallRatio + 0.1)) {
myself.stageRatio = smallRatio;
myself.setExtent(world.extent());
delete myself.step;
}
};
}
function zoomOut() {
function zoomTo(targetRatio) {
var count = 1,
steps = 5;
myself.fps = 30;
myself.isSmallStage = true;
myself.step = function () {
myself.stageRatio += (1 - myself.stageRatio) / 2;
myself.setExtent(world.extent());
if (myself.stageRatio > 0.9) {
myself.stageRatio = 1;
myself.isSmallStage = false;
myself.setExtent(world.extent());
myself.controlBar.stageSizeButton.refresh();
var diff;
if (count >= steps) {
myself.stageRatio = targetRatio;
delete myself.step;
myself.fps = 0;
myself.isSmallStage = !(targetRatio === 1);
myself.controlBar.stageSizeButton.refresh();
} else {
count += 1;
diff = (targetRatio - myself.stageRatio) / 2;
myself.stageRatio += diff;
}
myself.setExtent(world.extent());
};
}
@ -3515,14 +3587,20 @@ IDE_Morph.prototype.toggleStageSize = function (isSmall) {
if (!this.isSmallStage || (smallRatio === this.stageRatio)) {
toggle();
}
} else if (altClicked) {
smallRatio = this.width() / 2 /
this.stage.dimensions.x;
if (!this.isSmallStage || (smallRatio === this.stageRatio)) {
toggle();
}
} else {
toggle();
}
if (this.isAnimating) {
if (this.isSmallStage) {
zoomIn();
zoomTo(smallRatio);
} else {
zoomOut();
zoomTo(1);
}
} else {
if (this.isSmallStage) {this.stageRatio = smallRatio; }
@ -4219,7 +4297,7 @@ IDE_Morph.prototype.getURLsbeOrRelative = function (url) {
var request = new XMLHttpRequest(),
myself = this;
try {
request.open('GET', baseUrl + url, false);
request.open('GET', baseURL + url, false);
request.send();
if (request.status === 200) {
return request.responseText;
@ -4660,7 +4738,7 @@ ProjectDialogMorph.prototype.setSource = function (source) {
myself.nameField.setContents(item.name || '');
}
src = myself.ide.getURL(
baseUrl + 'Examples/' + item.name + '.xml'
baseURL + 'Examples/' + item.name + '.xml'
);
xml = myself.ide.serializer.parse(src);
@ -4714,9 +4792,9 @@ ProjectDialogMorph.prototype.getLocalProjectList = function () {
ProjectDialogMorph.prototype.getExamplesProjectList = function () {
var dir,
projects = [];
//alert(baseUrl);
//alert(baseURL);
dir = this.ide.getURL(baseUrl + 'Examples/');
dir = this.ide.getURL(baseURL + 'Examples/');
dir.split('\n').forEach(
function (line) {
var startIdx = line.search(new RegExp('href=".*xml"')),
@ -4835,7 +4913,7 @@ ProjectDialogMorph.prototype.openProject = function () {
if (this.source === 'cloud') {
this.openCloudProject(proj);
} else if (this.source === 'examples') {
src = this.ide.getURL(baseUrl + 'Examples/' + proj.name + '.xml');
src = this.ide.getURL(baseURL + 'Examples/' + proj.name + '.xml');
this.ide.openProjectString(src);
this.destroy();
} else { // 'local'
@ -5042,7 +5120,7 @@ ProjectDialogMorph.prototype.shareProject = function () {
projectId = 'Username=' +
encodeURIComponent(usr.toLowerCase()) +
'&ProjectName=' +
encodeURIComponent(proj.projectName);
encodeURIComponent(proj.ProjectName);
location.hash = projectId;
}
},
@ -5214,7 +5292,7 @@ function SpriteIconMorph(aSprite, aTemplate) {
}
SpriteIconMorph.prototype.init = function (aSprite, aTemplate) {
var colors, action, query, myself = this;
var colors, action, query, hover, myself = this;
if (!aTemplate) {
colors = [
@ -5244,6 +5322,11 @@ SpriteIconMorph.prototype.init = function (aSprite, aTemplate) {
return false;
};
hover = function () {
if (!aSprite.exemplar) {return null; }
return (localize('parent' + ':\n' + aSprite.exemplar.name));
};
// additional properties:
this.object = aSprite || new SpriteMorph(); // mandatory, actually
this.version = this.object.version;
@ -5259,7 +5342,7 @@ SpriteIconMorph.prototype.init = function (aSprite, aTemplate) {
this.object.name, // label string
query, // predicate/selector
null, // environment
null, // hint
hover, // hint
aTemplate // optional, for cached background images
);
@ -5430,6 +5513,9 @@ SpriteIconMorph.prototype.userMenu = function () {
menu.addItem("duplicate", 'duplicateSprite');
menu.addItem("delete", 'removeSprite');
menu.addLine();
if (StageMorph.prototype.enableInheritance) {
menu.addItem("parent...", 'chooseExemplar');
}
if (this.object.anchor) {
menu.addItem(
localize('detach from') + ' ' + this.object.anchor.name,
@ -5464,6 +5550,10 @@ SpriteIconMorph.prototype.exportSprite = function () {
this.object.exportSprite();
};
SpriteIconMorph.prototype.chooseExemplar = function () {
this.object.chooseExemplar();
};
SpriteIconMorph.prototype.showSpriteOnStage = function () {
this.object.showOnStage();
};
@ -6483,3 +6573,148 @@ JukeboxMorph.prototype.reactToDropOf = function (icon) {
this.sprite.sounds.add(costume, idx);
this.updateList();
};
// StageHandleMorph ////////////////////////////////////////////////////////
// I am a horizontal resizing handle for a StageMorph
// StageHandleMorph inherits from Morph:
StageHandleMorph.prototype = new Morph();
StageHandleMorph.prototype.constructor = StageHandleMorph;
StageHandleMorph.uber = Morph.prototype;
// StageHandleMorph instance creation:
function StageHandleMorph(target) {
this.init(target);
}
StageHandleMorph.prototype.init = function (target) {
this.target = target || null;
HandleMorph.uber.init.call(this);
this.color = MorphicPreferences.isFlat ?
IDE_Morph.prototype.groupColor : new Color(190, 190, 190);
this.isDraggable = false;
this.noticesTransparentClick = true;
this.setExtent(new Point(12, 50));
};
// StageHandleMorph drawing:
StageHandleMorph.prototype.drawNew = function () {
this.normalImage = newCanvas(this.extent());
this.highlightImage = newCanvas(this.extent());
this.drawOnCanvas(
this.normalImage,
this.color
);
this.drawOnCanvas(
this.highlightImage,
MorphicPreferences.isFlat ?
new Color(245, 245, 255) : new Color(100, 100, 255),
this.color
);
this.image = this.normalImage;
this.fixLayout();
};
StageHandleMorph.prototype.drawOnCanvas = function (
aCanvas,
color,
shadowColor
) {
var context = aCanvas.getContext('2d'),
l = aCanvas.height / 8,
w = aCanvas.width / 6,
r = w / 2,
x,
y,
i;
context.lineWidth = w;
context.lineCap = 'round';
y = aCanvas.height / 2;
context.strokeStyle = color.toString();
x = aCanvas.width / 12;
for (i = 0; i < 3; i += 1) {
if (i > 0) {
context.beginPath();
context.moveTo(x, y - (l - r));
context.lineTo(x, y + (l - r));
context.stroke();
}
x += (w * 2);
l *= 2;
}
if (shadowColor) {
context.strokeStyle = shadowColor.toString();
x = aCanvas.width / 12 + w;
l = aCanvas.height / 8;
for (i = 0; i < 3; i += 1) {
if (i > 0) {
context.beginPath();
context.moveTo(x, y - (l - r));
context.lineTo(x, y + (l - r));
context.stroke();
}
x += (w * 2);
l *= 2;
}
}
};
// StageHandleMorph layout:
StageHandleMorph.prototype.fixLayout = function () {
if (!this.target) {return; }
var ide = this.target.parentThatIsA(IDE_Morph);
this.setTop(this.target.top() + 10);
this.setRight(this.target.left());
if (ide) {ide.add(this); } // come to front
};
// StageHandleMorph stepping:
StageHandleMorph.prototype.step = null;
StageHandleMorph.prototype.mouseDownLeft = function (pos) {
var world = this.world(),
offset = this.right() - pos.x,
myself = this,
ide = this.target.parentThatIsA(IDE_Morph);
if (!this.target) {
return null;
}
ide.isSmallStage = true;
ide.controlBar.stageSizeButton.refresh();
this.step = function () {
var newPos, newWidth;
if (world.hand.mouseButton) {
newPos = world.hand.bounds.origin.x + offset;
newWidth = myself.target.right() - newPos;
ide.stageRatio = newWidth / myself.target.dimensions.x;
ide.setExtent(world.extent());
} else {
this.step = null;
ide.isSmallStage = !(ide.stageRatio === 1);
ide.controlBar.stageSizeButton.refresh();
}
};
};
// StageHandleMorph events:
StageHandleMorph.prototype.mouseEnter = function () {
this.image = this.highlightImage;
this.changed();
};
StageHandleMorph.prototype.mouseLeave = function () {
this.image = this.normalImage;
this.changed();
};

Plik binarny nie jest wyświetlany.

Wyświetl plik

@ -2522,8 +2522,35 @@ ______
* Morphic, Objects, Blocks, XML: Optimizations and dramatic speed-up. Thanks, Nathan!!
* Objects: push maximum clone count up to 1000, tweak Note::play
=== Start with v4.0.1 ===
=== v4.0.1 (unreleased) ===
150626
------
* Morphic: Fix Inspector duplication, update documentation
150727
------
* Polish translation update, thanks, Bartosz Leper!
* Turkish translation. Yay!! Thanks, Hakan Ataş!
* Hungarian translation. Yay!! Thanks, Makány György!
* GUI: relative-url fixes, Thanks, Michael!
* Morphic: enable exporting a screenshot of the World
* Morphic: enable more fine-grained control over dragging position correction
* Morphic: enable all Morphs to “scrollIntoView()”
* Morpic: keyboard accessibility for menus
* Objects: fixes and enhancements for nested sprites
* Blocks, Objects, BYOB, GUI: keyboard editing support
* Objects, Blocks, Threads, GUI, Store, Widgets: Prototypal inheritance for sprite-local variables
* Objects, Blocks: enable monitoring closurized non-locals and thread-temporaries (script vars of running processes)
* GUI: stage resizing handle
150728
------
* GUI: fixed relative urls, thanks, Michael!
* Morphic: escalate origin with “accept” and “cancel” events from text cursors
* BYOB: keep BlockEditors open when <enter> or <esc> keys are pressed
* GUI: stop keyboard editing of blocks when selecting another sprite
150730
------
* Blocks: improve keyboard editing for embedded rings

1695
lang-hu.js 100644

Plik diff jest za duży Load Diff

Wyświetl plik

@ -248,8 +248,8 @@ SnapTranslator.dict.pl = {
'tylko lewo/prawo',
// new sprite button:
'add a new sprite':
'dodaj nowego duszka',
'add a new Turtle sprite':
'dodaj nowego duszka-żółwia',
// tab help
'costumes tab help':
@ -343,7 +343,7 @@ SnapTranslator.dict.pl = {
'think %s':
'pomy\u015Bl %s',
'Hello!':
'Hallo!',
'Cześć!',
'Hmm...':
'Hmm...',
'change %eff effect by %n':
@ -545,9 +545,9 @@ SnapTranslator.dict.pl = {
'join %words':
'po\u0142\u0105cz %words',
'hello':
'Hallo',
'witaj',
'world':
's\u0142owo',
'świecie',
'letter %n of %s':
'litera %n z %s',
'length of %s':
@ -673,6 +673,8 @@ SnapTranslator.dict.pl = {
'Logowanie...',
'Signup...':
'Rejestracja...',
'Reset Password...':
'Zresetuj hasło...',
// settings menu
'Language...':
@ -857,7 +859,7 @@ SnapTranslator.dict.pl = {
'Ok':
'Ok',
'Cancel':
'Poniechaj',
'Anuluj',
'Yes':
'Tak',
'No':
@ -903,9 +905,53 @@ SnapTranslator.dict.pl = {
'Delete Project':
'Usu\u0144 projekt',
'Are you sure you want to delete':
'Czy napewno chcesz usun\u0105\u0107?',
'Czy napewno chcesz usun\u0105\u0107',
'rename...':
'przemianuj',
'Cloud':
'Chmura',
'Browser':
'Przeglądarka',
'Examples':
'Przykłady',
'You are not logged in':
'Nie jesteś zalogowany',
'Updating\nproject list...':
'Aktualizowanie\nlisty projektów...',
'last changed':
'ostatnio zmieniony',
'Open':
'Otwórz',
'Share':
'Udostępnij',
'Unshare':
'Wyłącz udostępnianie',
'Share Project':
'Udostępnij projekt',
'Unshare Project':
'Wyłącz udostępnianie projektu',
'Are you sure you want to publish':
'Czy na pewno chcesz opublikować projekt',
'Are you sure you want to unpublish':
'Czy na pewno chcesz wyłączyć publikowanie projektu',
'sharing\nproject...':
'Udostępnianie\nprojektu...',
'shared.':
'Projekt udostępniony.',
'unsharing\nproject...':
'Wyłączanie\nudostępniania projektu...',
'unshared.':
'Udostępnianie wyłączone.',
'Fetching project\nfrom the cloud...':
'Wczytywanie projektu\nz chmury...',
'Opening project...':
'Otwieranie projektu...',
'Save Project':
'Zapisz projekt',
'Saving project\nto the cloud...':
'Zapisywanie projektu\ndo chmury...',
'saved.':
'Projekt zapisany.',
// costume editor
'Costume Editor':
@ -1081,7 +1127,7 @@ SnapTranslator.dict.pl = {
// costumes
'Turtle':
'Duszek',
'Żółw',
'Empty':
'Pusty',
@ -1221,5 +1267,61 @@ SnapTranslator.dict.pl = {
'last':
'ostatni',
'any':
'dowolny'
'dowolny',
// Sign up dialog
'Sign up':
'Rejestracja',
'User name:':
'Nazwa użytkownika:',
'Birth date:':
'Data urodzenia:',
'year:':
'rok:',
'E-mail address:':
'Adres e-mail:',
'E-mail address of parent or guardian:':
'Adres e-mail rodzica lub opiekuna:',
'Terms of Service...':
'Regulamin...',
'Privacy...':
'Polityka prywatności...',
'I have read and agree\nto the Terms of Service':
'Przeczytałem i zgadzam się\nz Regulaminem',
'January':
'styczeń',
'February':
'luty',
'March':
'marzec',
'April':
'kwiecień',
'May':
'maj',
'June':
'czerwiec',
'July':
'lipiec',
'August':
'sierpień',
'September':
'wrzesień',
'October':
'październik',
'November':
'listopad',
'December':
'grudzień',
'please fill out\nthis field':
'Proszę wypełnić\nto pole',
'please agree to\nthe TOS':
'Proszę zaakceptować\nRegulamin',
'Sign in':
'Zaloguj się',
'Password:':
'Hasło:',
'stay signed in on this computer\nuntil logging out':
'Zapamiętaj mnie na tym komputerze\naż do wylogowania',
'Reset password':
'Zresetuj hasło'
};

1275
lang-tr.js 100644

Plik diff jest za duży Load Diff

Wyświetl plik

@ -3,3 +3,5 @@ list-utilities List utilities
stream-tools Streams (lazy lists)
variadic-reporters Variadic reporters
word-sentence Words, sentences
cases Multi-branched conditional (switch)
leap-library LEAP Motion controller

Wyświetl plik

@ -0,0 +1 @@
<blocks app="Snap! 4.0, http://snap.berkeley.edu" version="1"><block-definition s="cases: if %&apos;test&apos; then %&apos;result&apos; %&apos;more&apos;" type="command" category="control"><header></header><code></code><inputs><input type="%b"></input><input type="%cs"></input><input type="%mult%boolUE"></input></inputs><script><block s="doIfElse"><block var="test"/><script><block s="doRun"><block var="result"/><list></list></block></script><script><custom-block s="catch %upvar %cs"><l>tag</l><script><custom-block s="for each %upvar of %l %cs"><l>item</l><block var="more"/><script><block s="doIf"><block s="evaluate"><block var="item"/><list></list></block><script><custom-block s="throw %s"><block var="tag"/></custom-block></script></block></script></custom-block></script></custom-block></script></block></script></block-definition><block-definition s="catch %&apos;tag&apos; %&apos;action&apos;" type="command" category="control"><header></header><code></code><inputs><input type="%upvar"></input><input type="%cs"></input></inputs><script><block s="doCallCC"><block s="reifyScript"><script><block s="doSetVar"><l>tag</l><block var="cont"/></block><block s="doRun"><block var="action"/><list></list></block></script><list><l>cont</l></list></block></block></script></block-definition><block-definition s="throw %&apos;cont&apos;" type="command" category="control"><header></header><code></code><inputs><input type="%s">catchtag</input></inputs><script><block s="doRun"><block var="cont"/><list></list></block></script></block-definition><block-definition s="for each %&apos;item&apos; of %&apos;data&apos; %&apos;action&apos;" type="command" category="lists"><header></header><code></code><inputs><input type="%upvar"></input><input type="%l"></input><input type="%cs"></input></inputs><script><block s="doUntil"><custom-block s="empty? %l"><block var="data"/></custom-block><script><block s="doSetVar"><l>item</l><block s="reportListItem"><l>1</l><block var="data"/></block></block><block s="doRun"><block var="action"/><list><block s="reportListItem"><l>1</l><block var="data"/></block></list></block><block s="doSetVar"><l>data</l><block s="reportCDR"><block var="data"/></block></block></script></block></script></block-definition><block-definition s="else if %&apos;test&apos; then %&apos;action&apos;" type="predicate" category="control"><header></header><code></code><inputs><input type="%b"></input><input type="%cs"></input></inputs><script><block s="doIfElse"><block var="test"/><script><block s="doRun"><block var="action"/><list></list></block><block s="doReport"><block s="reportTrue"></block></block></script><script><block s="doReport"><block s="reportFalse"></block></block></script></block></script></block-definition><block-definition s="else %&apos;action&apos;" type="predicate" category="control"><header></header><code></code><inputs><input type="%cs"></input></inputs><script><block s="doRun"><block var="action"/><list></list></block><block s="doReport"><block s="reportTrue"></block></block></script></block-definition></blocks>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Wyświetl plik

@ -61,7 +61,7 @@ PushButtonMorph, SyntaxElementMorph, Color, Point, WatcherMorph,
StringMorph, SpriteMorph, ScrollFrameMorph, CellMorph, ArrowMorph,
MenuMorph, snapEquals, Morph, isNil, localize, MorphicPreferences*/
modules.lists = '2015-June-25';
modules.lists = '2015-July-27';
var List;
var ListWatcherMorph;
@ -158,9 +158,8 @@ List.prototype.add = function (element, index) {
if no index is specifed, append the element
*/
var idx = index || this.length() + 1,
obj = element === 0 ? 0
: element === false ? false
: element || null;
obj = isNil(element) ? null : element;
this.becomeArray();
this.contents.splice(idx - 1, 0, obj);
this.changed();

Wyświetl plik

@ -42,7 +42,7 @@
/*global modules, contains*/
modules.locale = '2015-June-25';
modules.locale = '2015-July-27';
// Global stuff
@ -475,3 +475,28 @@ SnapTranslator.dict.te = {
'last_changed':
'2015-02-20'
};
SnapTranslator.dict.tr = {
// translations meta information
'language_name':
'Türkçe',
'language_translator':
'Hakan Atas',
'translator_e-mail':
'hakanatas@gmail.com',
'last_changed':
'2015-7-27'
};
SnapTranslator.dict.hu = {
// translations meta information
'language_name':
'Magyar',
'language_translator':
'Makány György',
'translator_e-mail':
'makany.gyorgy@gmail.com',
'last_changed':
'2015-07-27'
};

Wyświetl plik

@ -1048,7 +1048,7 @@
/*global window, HTMLCanvasElement, getMinimumFontHeight, FileReader, Audio,
FileList, getBlurredShadowSupport*/
var morphicVersion = '2015-June-26';
var morphicVersion = '2015-July-28';
var modules = {}; // keep track of additional loaded modules
var useBlurredShadows = getBlurredShadowSupport(); // check for Chrome-bug
@ -2501,6 +2501,32 @@ Morph.prototype.keepWithin = function (aMorph) {
}
};
Morph.prototype.scrollIntoView = function () {
var leftOff, rightOff, topOff, bottomOff,
sf = this.parentThatIsA(ScrollFrameMorph);
if (!sf) {return; }
rightOff = Math.min(
this.fullBounds().right() - sf.right(),
sf.contents.right() - sf.right()
);
if (rightOff > 0) {
sf.contents.moveBy(new Point(-rightOff, 0));
}
leftOff = this.fullBounds().left() - sf.left();
if (leftOff < 0) {
sf.contents.moveBy(new Point(-leftOff, 0));
}
topOff = this.fullBounds().top() - sf.top();
if (topOff < 0) {
sf.contents.moveBy(new Point(0, -topOff));
}
bottomOff = this.fullBounds().bottom() - sf.bottom();
if (bottomOff > 0) {
sf.contents.moveBy(new Point(0, -bottomOff));
}
sf.adjustScrollBars();
};
// Morph accessing - dimensional changes requiring a complete redraw
Morph.prototype.setExtent = function (aPoint) {
@ -3092,6 +3118,13 @@ Morph.prototype.rootForGrab = function () {
return this.parent.rootForGrab();
};
Morph.prototype.isCorrectingOutsideDrag = function () {
// make sure I don't "trail behind" the hand when dragged
// override for morphs that you want to be dragged outside
// their full bounds
return true;
};
Morph.prototype.wantsDropOf = function (aMorph) {
// default is to answer the general flag - change for my heirs
if ((aMorph instanceof HandleMorph) ||
@ -3174,6 +3207,17 @@ Morph.prototype.move = function () {
);
};
Morph.prototype.moveCenter = function () {
this.world().activeHandle = new HandleMorph(
this,
null,
null,
null,
null,
'moveCenter'
);
};
Morph.prototype.hint = function (msg) {
var m, text;
text = msg;
@ -3722,7 +3766,7 @@ HandleMorph.prototype.init = function (
this.target = target || null;
this.minExtent = new Point(minX || 0, minY || 0);
this.inset = new Point(insetX || 0, insetY || insetX || 0);
this.type = type || 'resize'; // can also be 'move'
this.type = type || 'resize'; // can also be 'move', 'moveCenter'
HandleMorph.uber.init.call(this);
this.color = new Color(255, 255, 255);
this.isDraggable = false;
@ -3747,11 +3791,15 @@ HandleMorph.prototype.drawNew = function () {
);
this.image = this.normalImage;
if (this.target) {
this.setPosition(
this.target.bottomRight().subtract(
this.extent().add(this.inset)
)
);
if (this.type === 'moveCenter') {
this.setCenter(this.target.center());
} else { // 'resize', 'move'
this.setPosition(
this.target.bottomRight().subtract(
this.extent().add(this.inset)
)
);
}
this.target.add(this);
this.target.changed();
}
@ -3763,6 +3811,7 @@ HandleMorph.prototype.drawOnCanvas = function (
shadowColor
) {
var context = aCanvas.getContext('2d'),
isSquare = (this.type.indexOf('move') === 0),
p1,
p11,
p2,
@ -3774,7 +3823,7 @@ HandleMorph.prototype.drawOnCanvas = function (
context.strokeStyle = color.toString();
if (this.type === 'move') {
if (isSquare) {
p1 = this.bottomLeft().subtract(this.position());
p11 = p1.copy();
@ -3811,7 +3860,7 @@ HandleMorph.prototype.drawOnCanvas = function (
context.strokeStyle = shadowColor.toString();
if (this.type === 'move') {
if (isSquare) {
p1 = this.bottomLeft().subtract(this.position());
p11 = p1.copy();
@ -3853,12 +3902,17 @@ HandleMorph.prototype.step = null;
HandleMorph.prototype.mouseDownLeft = function (pos) {
var world = this.root(),
offset = pos.subtract(this.bounds.origin),
offset,
myself = this;
if (!this.target) {
return null;
}
if (this.type === 'moveCenter') {
offset = pos.subtract(this.center());
} else {
offset = pos.subtract(this.bounds.origin);
}
this.step = function () {
var newPos, newExt;
if (world.hand.mouseButton) {
@ -3875,6 +3929,8 @@ HandleMorph.prototype.mouseDownLeft = function (pos) {
myself.extent().add(myself.inset)
)
);
} else if (this.type === 'moveCenter') {
myself.target.setCenter(newPos);
} else { // type === 'move'
myself.target.setPosition(
newPos.subtract(this.target.extent())
@ -4680,7 +4736,7 @@ CursorMorph.prototype.accept = function () {
if (world) {
world.stopEditing();
}
this.escalateEvent('accept', null);
this.escalateEvent('accept', this);
};
CursorMorph.prototype.cancel = function () {
@ -4689,7 +4745,7 @@ CursorMorph.prototype.cancel = function () {
if (world) {
world.stopEditing();
}
this.escalateEvent('cancel', null);
this.escalateEvent('cancel', this);
};
CursorMorph.prototype.undo = function () {
@ -6652,6 +6708,8 @@ MenuMorph.prototype.init = function (target, title, environment, fontSize) {
this.label = null;
this.world = null;
this.isListContents = false;
this.hasFocus = false;
this.selection = null;
// initialize inherited properties:
MenuMorph.uber.init.call(this);
@ -6871,6 +6929,7 @@ MenuMorph.prototype.popup = function (world, pos) {
}
world.add(this);
world.activeMenu = this;
this.world = world; // optionally enable keyboard support
this.fullChanged();
};
@ -6901,6 +6960,105 @@ MenuMorph.prototype.popUpCenteredInWorld = function (world) {
);
};
// MenuMorph keyboard accessibility
MenuMorph.prototype.getFocus = function () {
this.world.keyboardReceiver = this;
this.selection = null;
this.selectFirst();
this.hasFocus = true;
};
MenuMorph.prototype.processKeyDown = function (event) {
//console.log(event.keyCode);
switch (event.keyCode) {
case 13: // 'enter'
case 32: // 'space'
if (this.selection) {
this.selection.mouseClickLeft();
}
return;
case 27: // 'esc'
return this.destroy();
case 38: // 'up arrow'
return this.selectUp();
case 40: // 'down arrow'
return this.selectDown();
default:
nop();
}
};
MenuMorph.prototype.processKeyUp = function (event) {
nop(event);
};
MenuMorph.prototype.processKeyPress = function (event) {
nop(event);
};
MenuMorph.prototype.selectFirst = function () {
var i;
for (i = 0; i < this.children.length; i += 1) {
if (this.children[i] instanceof MenuItemMorph) {
this.select(this.children[i]);
return;
}
}
};
MenuMorph.prototype.selectUp = function () {
var triggers, idx;
triggers = this.children.filter(function (each) {
return each instanceof MenuItemMorph;
});
if (!this.selection) {
if (triggers.length) {
this.select(triggers[0]);
}
return;
}
idx = triggers.indexOf(this.selection) - 1;
if (idx < 0) {
idx = triggers.length - 1;
}
this.select(triggers[idx]);
};
MenuMorph.prototype.selectDown = function () {
var triggers, idx;
triggers = this.children.filter(function (each) {
return each instanceof MenuItemMorph;
});
if (!this.selection) {
if (triggers.length) {
this.select(triggers[0]);
}
return;
}
idx = triggers.indexOf(this.selection) + 1;
if (idx >= triggers.length) {
idx = 0;
}
this.select(triggers[idx]);
};
MenuMorph.prototype.select = function (aMenuItem) {
this.unselectAllItems();
aMenuItem.image = aMenuItem.highlightImage;
aMenuItem.changed();
this.selection = aMenuItem;
};
MenuMorph.prototype.destroy = function () {
if (this.hasFocus) {
this.world.keyboardReceiver = null;
}
MenuMorph.uber.destroy.call(this);
};
// StringMorph /////////////////////////////////////////////////////////
// I am a single line of text
@ -9586,32 +9744,16 @@ HandMorph.prototype.processMouseMove = function (event) {
this.grabOrigin = this.morphToGrab.situation();
}
if (morph) {
// if the mouse has left its fullBounds, center it
// if the mouse has left its fullBounds, allow to center it
fb = morph.fullBounds();
if (!fb.containsPoint(pos)) {
if (!fb.containsPoint(pos) &&
morph.isCorrectingOutsideDrag()) {
this.bounds.origin = fb.center();
this.grab(morph);
this.setPosition(pos);
}
}
}
/*
original, more cautious code for grabbing Morphs,
retained in case of needing to fall back:
if (morph === this.morphToGrab) {
if (morph.isDraggable) {
this.grab(morph);
} else if (morph.isTemplate) {
morph = morph.fullCopy();
morph.isTemplate = false;
morph.isDraggable = true;
this.grab(morph);
}
}
*/
}
this.mouseOverList.forEach(function (old) {
@ -10399,6 +10541,13 @@ WorldMorph.prototype.contextMenu = function () {
'inspect',
'open a window on\nall properties'
);
menu.addItem(
"screenshot...",
function () {
window.open(this.fullImageClassic().toDataURL());
},
'open a new window\nwith a picture of this morph'
);
menu.addLine();
menu.addItem(
"restore display",

Wyświetl plik

@ -125,7 +125,7 @@ PrototypeHatBlockMorph*/
// Global stuff ////////////////////////////////////////////////////////
modules.objects = '2015-June-25';
modules.objects = '2015-July-27';
var SpriteMorph;
var StageMorph;
@ -583,7 +583,7 @@ SpriteMorph.prototype.initBlocks = function () {
},
/* migrated to a newer block version:
receiveClick: {
type: 'hat',
category: 'control',
@ -900,17 +900,20 @@ SpriteMorph.prototype.initBlocks = function () {
reifyScript: {
type: 'ring',
category: 'other',
spec: '%rc %ringparms'
spec: '%rc %ringparms',
alias: 'command ring lambda'
},
reifyReporter: {
type: 'ring',
category: 'other',
spec: '%rr %ringparms'
spec: '%rr %ringparms',
alias: 'reporter ring lambda'
},
reifyPredicate: {
type: 'ring',
category: 'other',
spec: '%rp %ringparms'
spec: '%rp %ringparms',
alias: 'predicate ring lambda'
},
reportSum: {
type: 'reporter',
@ -920,12 +923,14 @@ SpriteMorph.prototype.initBlocks = function () {
reportDifference: {
type: 'reporter',
category: 'operators',
spec: '%n \u2212 %n'
spec: '%n \u2212 %n',
alias: '-'
},
reportProduct: {
type: 'reporter',
category: 'operators',
spec: '%n \u00D7 %n'
spec: '%n \u00D7 %n',
alias: '*'
},
reportQuotient: {
type: 'reporter',
@ -1103,6 +1108,13 @@ SpriteMorph.prototype.initBlocks = function () {
spec: 'script variables %scriptVars'
},
// inheritance - experimental
doDeleteAttr: {
type: 'command',
category: 'variables',
spec: 'delete %shd'
},
// Lists
reportNewList: {
type: 'reporter',
@ -1348,11 +1360,13 @@ SpriteMorph.prototype.init = function (globals) {
'confetti': 0
};
// sprite inheritance
this.exemplar = null;
SpriteMorph.uber.init.call(this);
this.isDraggable = true;
this.isDown = false;
this.heading = 90;
this.changed();
this.drawNew();
@ -1642,7 +1656,8 @@ SpriteMorph.prototype.variableBlock = function (varName) {
SpriteMorph.prototype.blockTemplates = function (category) {
var blocks = [], myself = this, varNames, button,
cat = category || 'motion', txt;
cat = category || 'motion', txt,
inheritedVars = this.inheritedVariableNames();
function block(selector) {
if (StageMorph.prototype.hiddenPrimitives[selector]) {
@ -1657,6 +1672,9 @@ SpriteMorph.prototype.blockTemplates = function (category) {
var newBlock = SpriteMorph.prototype.variableBlock(varName);
newBlock.isDraggable = false;
newBlock.isTemplate = true;
if (contains(inheritedVars, varName)) {
newBlock.ghost();
}
return newBlock;
}
@ -1705,15 +1723,18 @@ SpriteMorph.prototype.blockTemplates = function (category) {
}
function addVar(pair) {
var ide;
if (pair) {
if (myself.variables.silentFind(pair[0])) {
if (myself.isVariableNameInUse(pair[0], pair[1])) {
myself.inform('that name is already in use');
} else {
ide = myself.parentThatIsA(IDE_Morph);
myself.addVariable(pair[0], pair[1]);
myself.toggleVariableWatcher(pair[0], pair[1]);
myself.blocksCache[cat] = null;
myself.paletteCache[cat] = null;
myself.parentThatIsA(IDE_Morph).refreshPalette();
if (!myself.showingVariableWatcher(pair[0])) {
myself.toggleVariableWatcher(pair[0], pair[1]);
}
ide.flushBlocksCache('variables'); // b/c of inheritance
ide.refreshPalette();
}
}
}
@ -2028,7 +2049,7 @@ SpriteMorph.prototype.blockTemplates = function (category) {
button.showHelp = BlockMorph.prototype.showHelp;
blocks.push(button);
if (this.variables.allNames().length > 0) {
if (this.deletableVariableNames().length > 0) {
button = new PushButtonMorph(
null,
function () {
@ -2037,7 +2058,7 @@ SpriteMorph.prototype.blockTemplates = function (category) {
null,
myself
);
myself.variables.allNames().forEach(function (name) {
myself.deletableVariableNames().forEach(function (name) {
menu.addItem(name, name);
});
menu.popUpAtHand(myself.world());
@ -2067,6 +2088,15 @@ SpriteMorph.prototype.blockTemplates = function (category) {
blocks.push(block('doHideVar'));
blocks.push(block('doDeclareVariables'));
// inheritance:
if (StageMorph.prototype.enableInheritance) {
blocks.push('-');
blocks.push(block('doDeleteAttr'));
}
///////////////////////////////
blocks.push('=');
blocks.push(block('reportNewList'));
@ -2357,15 +2387,30 @@ SpriteMorph.prototype.freshPalette = function (category) {
// SpriteMorph blocks searching
SpriteMorph.prototype.blocksMatching = function (searchString, strictly) {
SpriteMorph.prototype.blocksMatching = function (
searchString,
strictly,
types, // optional, ['hat', 'command', 'reporter', 'predicate']
varNames // optional, list of reachable unique variable names
) {
// answer an array of block templates whose spec contains
// the given search string, ordered by descending relevance
// types is an optional array containing block types the search
// is limited to, e.g. "command", "hat", "reporter", "predicate".
// Note that "predicate" is not subsumed by "reporter" and has
// to be specified explicitly.
// if no types are specified all blocks are searched
var blocks = [],
blocksDict,
myself = this,
search = searchString.toLowerCase(),
stage = this.parentThatIsA(StageMorph);
if (!types || !types.length) {
types = ['hat', 'command', 'reporter', 'predicate', 'ring'];
}
if (!varNames) {varNames = []; }
function labelOf(aBlockSpec) {
var words = (BlockMorph.prototype.parseSpec(aBlockSpec)),
filtered = words.filter(
@ -2396,29 +2441,39 @@ SpriteMorph.prototype.blocksMatching = function (searchString, strictly) {
return newBlock;
}
// variable getters
varNames.forEach(function (vName) {
var rel = relevance(labelOf(vName), search);
if (rel !== -1) {
blocks.push([myself.variableBlock(vName), rel + '1']);
}
});
// custom blocks
[this.customBlocks, stage.globalBlocks].forEach(function (blocksList) {
blocksList.forEach(function (definition) {
var spec = localize(definition.blockSpec()).toLowerCase(),
rel = relevance(labelOf(spec), search);
if (rel !== -1) {
blocks.push([definition.templateInstance(), rel + '1']);
if (contains(types, definition.type)) {
var spec = localize(definition.blockSpec()).toLowerCase(),
rel = relevance(labelOf(spec), search);
if (rel !== -1) {
blocks.push([definition.templateInstance(), rel + '2']);
}
}
});
});
// primitives
blocksDict = SpriteMorph.prototype.blocks;
Object.keys(blocksDict).forEach(function (selector) {
if (!StageMorph.prototype.hiddenPrimitives[selector]) {
if (!StageMorph.prototype.hiddenPrimitives[selector] &&
contains(types, blocksDict[selector].type)) {
var block = blocksDict[selector],
spec = localize(block.spec).toLowerCase(),
spec = localize(block.alias || block.spec).toLowerCase(),
rel = relevance(labelOf(spec), search);
if (
(rel !== -1) &&
(!block.dev) &&
(!block.only || (block.only === myself.constructor))
) {
blocks.push([primitive(selector), rel + '2']);
blocks.push([primitive(selector), rel + '3']);
}
}
});
@ -2426,18 +2481,43 @@ SpriteMorph.prototype.blocksMatching = function (searchString, strictly) {
return blocks.map(function (each) {return each[0]; });
};
SpriteMorph.prototype.searchBlocks = function () {
SpriteMorph.prototype.searchBlocks = function (
searchString,
types,
varNames,
scriptFocus
) {
var myself = this,
unit = SyntaxElementMorph.prototype.fontSize,
ide = this.parentThatIsA(IDE_Morph),
oldSearch = '',
searchBar = new InputFieldMorph(''),
searchPane = ide.createPalette('forSearch');
searchBar = new InputFieldMorph(searchString || ''),
searchPane = ide.createPalette('forSearch'),
blocksList = [],
selection,
focus;
function showSelection() {
if (focus) {focus.destroy(); }
if (!selection || !scriptFocus) {return; }
focus = selection.outline(
MorphicPreferences.isFlat ? new Color(150, 200, 255)
: new Color(255, 255, 255),
2
);
searchPane.contents.add(focus);
focus.scrollIntoView();
}
function show(blocks) {
var oldFlag = Morph.prototype.trackChanges,
x = searchPane.contents.left() + 5,
y = (searchBar.bottom() + unit);
blocksList = blocks;
selection = null;
if (blocks.length && scriptFocus) {
selection = blocks[0];
}
Morph.prototype.trackChanges = false;
searchPane.contents.children = [searchPane.contents.children[0]];
blocks.forEach(function (block) {
@ -2447,6 +2527,7 @@ SpriteMorph.prototype.searchBlocks = function () {
y += unit * 0.3;
});
Morph.prototype.trackChanges = oldFlag;
showSelection();
searchPane.changed();
}
@ -2463,17 +2544,52 @@ SpriteMorph.prototype.searchBlocks = function () {
searchBar.drawNew();
searchPane.accept = function () {
var search = searchBar.getValue();
if (search.length > 0) {
show(myself.blocksMatching(search));
var search;
if (scriptFocus) {
searchBar.cancel();
if (selection) {
scriptFocus.insertBlock(selection);
}
} else {
search = searchBar.getValue();
if (search.length > 0) {
show(myself.blocksMatching(search));
}
}
};
searchPane.reactToKeystroke = function () {
var search = searchBar.getValue();
if (search !== oldSearch) {
oldSearch = search;
show(myself.blocksMatching(search, search.length < 2));
searchPane.reactToKeystroke = function (evt) {
var search, idx, code = evt ? evt.keyCode : 0;
switch (code) {
case 38: // up arrow
if (!scriptFocus || !selection) {return; }
idx = blocksList.indexOf(selection) - 1;
if (idx < 0) {
idx = blocksList.length - 1;
}
selection = blocksList[idx];
showSelection();
return;
case 40: // down arrow
if (!scriptFocus || !selection) {return; }
idx = blocksList.indexOf(selection) + 1;
if (idx >= blocksList.length) {
idx = 0;
}
selection = blocksList[idx];
showSelection();
return;
default:
search = searchBar.getValue();
if (search !== oldSearch) {
oldSearch = search;
show(myself.blocksMatching(
search,
search.length < 2,
types,
varNames
));
}
}
};
@ -2484,6 +2600,7 @@ SpriteMorph.prototype.searchBlocks = function () {
ide.fixLayout('refreshPalette');
searchBar.edit();
if (searchString) {searchPane.reactToKeystroke(); }
};
// SpriteMorph variable management
@ -2491,7 +2608,7 @@ SpriteMorph.prototype.searchBlocks = function () {
SpriteMorph.prototype.addVariable = function (name, isGlobal) {
var ide = this.parentThatIsA(IDE_Morph);
if (isGlobal) {
this.variables.parentFrame.addVar(name);
this.globalVariables().addVar(name);
if (ide) {
ide.flushBlocksCache('variables');
}
@ -2503,7 +2620,10 @@ SpriteMorph.prototype.addVariable = function (name, isGlobal) {
SpriteMorph.prototype.deleteVariable = function (varName) {
var ide = this.parentThatIsA(IDE_Morph);
this.deleteVariableWatcher(varName);
if (!contains(this.inheritedVariableNames(true), varName)) {
// check only shadowed variables
this.deleteVariableWatcher(varName);
}
this.variables.deleteVar(varName);
if (ide) {
ide.flushBlocksCache('variables'); // b/c the var could be global
@ -2658,7 +2778,7 @@ SpriteMorph.prototype.userMenu = function () {
}
menu.addItem("duplicate", 'duplicate');
menu.addItem("delete", 'remove');
menu.addItem("move", 'move');
menu.addItem("move", 'moveCenter');
if (!this.isClone) {
menu.addItem("edit", 'edit');
}
@ -3176,12 +3296,20 @@ SpriteMorph.prototype.positionTalkBubble = function () {
SpriteMorph.prototype.prepareToBeGrabbed = function (hand) {
this.removeShadow();
this.recordLayers();
if (!this.bounds.containsPoint(hand.position())) {
if (!this.bounds.containsPoint(hand.position()) &&
this.isCorrectingOutsideDrag()) {
this.setCenter(hand.position());
}
this.addShadow();
};
SpriteMorph.prototype.isCorrectingOutsideDrag = function () {
// make sure I don't "trail behind" the hand when dragged
// override for morphs that you want to be dragged outside
// their full bounds
return !this.parts.length;
};
SpriteMorph.prototype.justDropped = function () {
this.restoreLayers();
this.positionTalkBubble();
@ -3240,6 +3368,22 @@ SpriteMorph.prototype.moveBy = function (delta, justMe) {
}
};
SpriteMorph.prototype.silentMoveBy = function (delta, justMe) {
SpriteMorph.uber.silentMoveBy.call(this, delta);
if (!justMe && this.parent instanceof HandMorph) {
this.parts.forEach(function (part) {
part.moveBy(delta);
});
}
};
SpriteMorph.prototype.rootForGrab = function () {
if (this.anchor) {
return this.anchor.rootForGrab();
}
return SpriteMorph.uber.rootForGrab.call(this);
};
SpriteMorph.prototype.slideBackTo = function (situation, inSteps) {
// override the inherited default to make sure my parts follow
var steps = inSteps || 5,
@ -3646,6 +3790,7 @@ SpriteMorph.prototype.reportThreadCount = function () {
SpriteMorph.prototype.findVariableWatcher = function (varName) {
var stage = this.parentThatIsA(StageMorph),
globals = this.globalVariables(),
myself = this;
if (stage === null) {
return null;
@ -3655,7 +3800,7 @@ SpriteMorph.prototype.findVariableWatcher = function (varName) {
function (morph) {
return morph instanceof WatcherMorph
&& (morph.target === myself.variables
|| morph.target === myself.variables.parentFrame)
|| morph.target === globals)
&& morph.getter === varName;
}
);
@ -3663,6 +3808,7 @@ SpriteMorph.prototype.findVariableWatcher = function (varName) {
SpriteMorph.prototype.toggleVariableWatcher = function (varName, isGlobal) {
var stage = this.parentThatIsA(StageMorph),
globals = this.globalVariables(),
watcher,
others;
if (stage === null) {
@ -3682,12 +3828,12 @@ SpriteMorph.prototype.toggleVariableWatcher = function (varName, isGlobal) {
// if no watcher exists, create a new one
if (isNil(isGlobal)) {
isGlobal = contains(this.variables.parentFrame.names(), varName);
isGlobal = contains(globals.names(), varName);
}
watcher = new WatcherMorph(
varName,
this.blockColor.variables,
isGlobal ? this.variables.parentFrame : this.variables,
isGlobal ? globals : this.variables,
varName
);
watcher.setPosition(stage.position().add(10));
@ -3954,6 +4100,176 @@ SpriteMorph.prototype.replaceDoubleDefinitionsFor = function (definition) {
}
};
// SpriteMorph inheritance - general
SpriteMorph.prototype.chooseExemplar = function () {
var stage = this.parentThatIsA(StageMorph),
myself = this,
other = stage.children.filter(function (m) {
return m instanceof SpriteMorph &&
(!contains(m.allExemplars(), myself));
}),
menu;
menu = new MenuMorph(
function (aSprite) {myself.setExemplar(aSprite); },
localize('current parent') +
':\n' +
(this.exemplar ? this.exemplar.name : localize('none'))
);
other.forEach(function (eachSprite) {
menu.addItem(eachSprite.name, eachSprite);
});
menu.addLine();
menu.addItem(localize('none'), null);
menu.popUpAtHand(this.world());
};
SpriteMorph.prototype.setExemplar = function (another) {
var ide = this.parentThatIsA(IDE_Morph);
this.exemplar = another;
if (isNil(another)) {
this.variables.parentFrame = (this.globalVariables());
} else {
this.variables.parentFrame = (another.variables);
}
if (ide) {
ide.flushBlocksCache('variables');
ide.refreshPalette();
}
};
SpriteMorph.prototype.allExemplars = function () {
// including myself
var all = [],
current = this;
while (!isNil(current)) {
all.push(current);
current = current.exemplar;
}
return all;
};
SpriteMorph.prototype.specimens = function () {
// without myself
var myself = this;
return this.siblings().filter(function (m) {
return m instanceof SpriteMorph && (m.exemplar === myself);
});
};
SpriteMorph.prototype.allSpecimens = function () {
// without myself
var myself = this;
return this.siblings().filter(function (m) {
return m instanceof SpriteMorph && contains(m.allExemplars(), myself);
});
};
// SpriteMorph inheritance - variables
SpriteMorph.prototype.isVariableNameInUse = function (vName, isGlobal) {
if (isGlobal) {
return contains(this.variables.allNames(), vName);
}
if (contains(this.variables.names(), vName)) {return true; }
return contains(this.globalVariables().names(), vName);
};
SpriteMorph.prototype.globalVariables = function () {
var current = this.variables.parentFrame;
while (current.owner) {
current = current.parentFrame;
}
return current;
};
SpriteMorph.prototype.shadowVar = function (name, value) {
var ide = this.parentThatIsA(IDE_Morph);
this.variables.addVar(name, value);
if (ide) {
ide.flushBlocksCache('variables');
ide.refreshPalette();
}
};
SpriteMorph.prototype.inheritedVariableNames = function (shadowedOnly) {
var names = [],
own = this.variables.names(),
current = this.variables.parentFrame;
function test(each) {
return shadowedOnly ? contains(own, each) : !contains(own, each);
}
while (current.owner instanceof SpriteMorph) {
names.push.apply(
names,
current.names().filter(test)
);
current = current.parentFrame;
}
return names;
};
SpriteMorph.prototype.deletableVariableNames = function () {
var locals = this.variables.names(),
inherited = this.inheritedVariableNames();
return locals.concat(
this.globalVariables().names().filter(
function (each) {
return !contains(locals, each) && !contains(inherited, each);
}
)
);
};
// SpriteMorph inheritance - custom blocks
/*
// under construction, commented out for now
SpriteMorph.prototype.ownBlocks = function () {
var dict = {};
this.customBlocks.forEach(function (def) {
dict[def.blockSpec()] = def;
});
return dict;
};
SpriteMorph.prototype.allBlocks = function (valuesOnly) {
var dict = {};
this.allExemplars().reverse().forEach(function (sprite) {
sprite.customBlocks.forEach(function (def) {
dict[def.blockSpec()] = def;
});
});
if (valuesOnly) {
return Object.keys(dict).map(function (key) {return dict[key]; });
}
return dict;
};
SpriteMorph.prototype.inheritedBlocks = function (valuesOnly) {
var dict = {},
own = Object.keys(this.ownBlocks()),
others = this.allExemplars().reverse();
others.pop();
others.forEach(function (sprite) {
sprite.customBlocks.forEach(function (def) {
var spec = def.blockSpec();
if (!contains(own, spec)) {
dict[spec] = def;
}
});
});
if (valuesOnly) {
return Object.keys(dict).map(function (key) {return dict[key]; });
}
return dict;
};
*/
// SpriteMorph thumbnail
SpriteMorph.prototype.thumbnail = function (extentPoint) {
@ -4334,6 +4650,8 @@ StageMorph.prototype.codeMappings = {};
StageMorph.prototype.codeHeaders = {};
StageMorph.prototype.enableCodeMapping = false;
StageMorph.prototype.enableInheritance = false;
// StageMorph instance creation
function StageMorph(globals) {
@ -4767,6 +5085,8 @@ StageMorph.prototype.processKeyEvent = function (event, action) {
keyName = 'enter';
if (event.ctrlKey || event.metaKey) {
keyName = 'ctrl enter';
} else if (event.shiftKey) {
keyName = 'shift enter';
}
break;
case 27:
@ -4807,6 +5127,9 @@ StageMorph.prototype.fireKeyEvent = function (key) {
if (evt === 'ctrl enter') {
return this.fireGreenFlagEvent();
}
if (evt === 'shift enter') {
return this.editScripts();
}
if (evt === 'ctrl f') {
if (!ide.isAppMode) {ide.currentSprite.searchBlocks(); }
return;
@ -4907,6 +5230,25 @@ StageMorph.prototype.removeAllClones = function () {
this.cloneCount = 0;
};
StageMorph.prototype.editScripts = function () {
var ide = this.parentThatIsA(IDE_Morph),
scripts,
sorted;
if (ide.isAppMode || !ScriptsMorph.prototype.enableKeyboard) {return; }
scripts = this.parentThatIsA(IDE_Morph).currentSprite.scripts;
scripts.edit(scripts.position());
sorted = scripts.focus.sortedScripts();
if (sorted.length) {
scripts.focus.element = sorted[0];
if (scripts.focus.element instanceof HatBlockMorph) {
scripts.focus.nextCommand();
}
} else {
scripts.focus.moveBy(new Point(50, 50));
}
scripts.focus.fixLayout();
};
// StageMorph block templates
StageMorph.prototype.blockTemplates = function (category) {
@ -4969,7 +5311,7 @@ StageMorph.prototype.blockTemplates = function (category) {
function addVar(pair) {
if (pair) {
if (myself.variables.silentFind(pair[0])) {
if (myself.isVariableNameInUse(pair[0])) {
myself.inform('that name is already in use');
} else {
myself.addVariable(pair[0], pair[1]);
@ -5271,9 +5613,7 @@ StageMorph.prototype.blockTemplates = function (category) {
blocks.push(block('doShowVar'));
blocks.push(block('doHideVar'));
blocks.push(block('doDeclareVariables'));
blocks.push('=');
blocks.push(block('reportNewList'));
blocks.push('-');
blocks.push(block('reportCONS'));
@ -5472,7 +5812,7 @@ StageMorph.prototype.show = function () {
this.changed();
};
// StageMorph cloning overrice
// StageMorph cloning override
StageMorph.prototype.createClone = nop;
@ -5663,6 +6003,18 @@ StageMorph.prototype.doubleDefinitionsFor
StageMorph.prototype.replaceDoubleDefinitionsFor
= SpriteMorph.prototype.replaceDoubleDefinitionsFor;
// StageMorph inheritance support - variables
StageMorph.prototype.isVariableNameInUse
= SpriteMorph.prototype.isVariableNameInUse;
StageMorph.prototype.globalVariables
= SpriteMorph.prototype.globalVariables;
StageMorph.prototype.inheritedVariableNames = function () {
return [];
};
// SpriteBubbleMorph ////////////////////////////////////////////////////////
/*
@ -6876,32 +7228,51 @@ WatcherMorph.prototype.isGlobal = function (selector) {
// WatcherMorph slider accessing:
WatcherMorph.prototype.setSliderMin = function (num) {
WatcherMorph.prototype.setSliderMin = function (num, noUpdate) {
if (this.target instanceof VariableFrame) {
this.sliderMorph.setSize(1);
this.sliderMorph.setStart(num);
this.sliderMorph.setSize(this.sliderMorph.rangeSize() / 5);
this.sliderMorph.setSize(1, noUpdate);
this.sliderMorph.setStart(num, noUpdate);
this.sliderMorph.setSize(this.sliderMorph.rangeSize() / 5, noUpdate);
}
};
WatcherMorph.prototype.setSliderMax = function (num) {
WatcherMorph.prototype.setSliderMax = function (num, noUpdate) {
if (this.target instanceof VariableFrame) {
this.sliderMorph.setSize(1);
this.sliderMorph.setStop(num);
this.sliderMorph.setSize(this.sliderMorph.rangeSize() / 5);
this.sliderMorph.setSize(1, noUpdate);
this.sliderMorph.setStop(num, noUpdate);
this.sliderMorph.setSize(this.sliderMorph.rangeSize() / 5, noUpdate);
}
};
// WatcherMorph updating:
WatcherMorph.prototype.update = function () {
var newValue,
num;
var newValue, sprite, num;
if (this.target && this.getter) {
this.updateLabel();
if (this.target instanceof VariableFrame) {
newValue = this.target.vars[this.getter] ?
this.target.vars[this.getter].value : undefined;
if (newValue === undefined && this.target.owner) {
sprite = this.target.owner;
if (contains(sprite.inheritedVariableNames(), this.getter)) {
newValue = this.target.getVar(this.getter);
// ghost cell color
this.cellMorph.setColor(
SpriteMorph.prototype.blockColor.variables
.lighter(35)
);
} else {
this.destroy();
return;
}
} else {
// un-ghost the cell color
this.cellMorph.setColor(
SpriteMorph.prototype.blockColor.variables
);
}
} else {
newValue = this.target[this.getter]();
}
@ -6986,7 +7357,11 @@ WatcherMorph.prototype.fixLayout = function () {
this.sliderMorph.button.pressColor.b += 100;
this.sliderMorph.setHeight(fontSize);
this.sliderMorph.action = function (num) {
myself.target.vars[myself.getter].value = Math.round(num);
myself.target.setVar(
myself.getter,
Math.round(num),
myself.target.owner
);
};
this.add(this.sliderMorph);
}
@ -7083,7 +7458,46 @@ WatcherMorph.prototype.userMenu = function () {
var myself = this,
menu = new MenuMorph(this),
on = '\u25CF',
off = '\u25CB';
off = '\u25CB',
vNames;
function monitor(vName) {
var stage = myself.parentThatIsA(StageMorph),
varFrame = myself.currentValue.outerContext.variables;
menu.addItem(
vName + '...',
function () {
var watcher = detect(
stage.children,
function (morph) {
return morph instanceof WatcherMorph
&& morph.target === varFrame
&& morph.getter === vName;
}
),
others;
if (watcher !== null) {
watcher.show();
watcher.fixLayout(); // re-hide hidden parts
return;
}
watcher = new WatcherMorph(
vName + ' ' + localize('(temporary)'),
SpriteMorph.prototype.blockColor.variables,
varFrame,
vName
);
watcher.setPosition(stage.position().add(10));
others = stage.watchers(watcher.left());
if (others.length > 0) {
watcher.setTop(others[others.length - 1].bottom());
}
stage.add(watcher);
watcher.fixLayout();
}
);
}
menu.addItem(
(this.style === 'normal' ? on : off) + ' ' + localize('normal'),
'styleNormal'
@ -7182,6 +7596,14 @@ WatcherMorph.prototype.userMenu = function () {
);
}
);
} else if (this.currentValue instanceof Context) {
vNames = this.currentValue.outerContext.variables.names();
if (vNames.length) {
menu.addLine();
vNames.forEach(function (vName) {
monitor(vName);
});
}
}
}
return menu;

124
store.js
Wyświetl plik

@ -61,7 +61,7 @@ SyntaxElementMorph, Variable*/
// Global stuff ////////////////////////////////////////////////////////
modules.store = '2015-June-25';
modules.store = '2015-July-27';
// XML_Serializer ///////////////////////////////////////////////////////
@ -413,6 +413,8 @@ SnapSerializer.prototype.rawLoadProjectModel = function (xmlNode) {
model.stage.attributes.threadsafe === 'true';
StageMorph.prototype.enableCodeMapping =
model.stage.attributes.codify === 'true';
StageMorph.prototype.enableInheritance =
model.stage.attributes.inheritance === 'true';
model.hiddenPrimitives = model.project.childNamed('hidden');
if (model.hiddenPrimitives) {
@ -459,9 +461,17 @@ SnapSerializer.prototype.rawLoadProjectModel = function (xmlNode) {
myself.loadValue(model);
});
// restore nesting associations
// restore inheritance and nesting associations
myself.project.stage.children.forEach(function (sprite) {
var anchor;
var exemplar, anchor;
if (sprite.inheritanceInfo) { // only sprites can inherit
exemplar = myself.project.sprites[
sprite.inheritanceInfo.exemplar
];
if (exemplar) {
sprite.setExemplar(exemplar);
}
}
if (sprite.nestingInfo) { // only sprites may have nesting info
anchor = myself.project.sprites[sprite.nestingInfo.anchor];
if (anchor) {
@ -471,6 +481,7 @@ SnapSerializer.prototype.rawLoadProjectModel = function (xmlNode) {
}
});
myself.project.stage.children.forEach(function (sprite) {
delete sprite.inheritanceInfo;
if (sprite.nestingInfo) { // only sprites may have nesting info
sprite.nestingScale = +(sprite.nestingInfo.scale || sprite.scale);
delete sprite.nestingInfo;
@ -491,7 +502,7 @@ SnapSerializer.prototype.rawLoadProjectModel = function (xmlNode) {
/* Watchers */
model.sprites.childrenNamed('watcher').forEach(function (model) {
var watcher, color, target, hidden, extX, extY, vFrame;
var watcher, color, target, hidden, extX, extY;
color = myself.loadColor(model.attributes.color);
target = Object.prototype.hasOwnProperty.call(
@ -512,20 +523,14 @@ SnapSerializer.prototype.rawLoadProjectModel = function (xmlNode) {
model.attributes,
'var'
)) {
vFrame = isNil(target) ? project.globalVariables
: target.variables;
if (Object.prototype.hasOwnProperty.call(
vFrame.vars,
model.attributes['var']
)) {
watcher = new WatcherMorph(
model.attributes['var'],
color,
vFrame,
model.attributes['var'],
hidden
);
}
watcher = new WatcherMorph(
model.attributes['var'],
color,
isNil(target) ? project.globalVariables
: target.variables,
model.attributes['var'],
hidden
);
} else {
watcher = new WatcherMorph(
localize(myself.watcherLabels[model.attributes.s]),
@ -535,35 +540,33 @@ SnapSerializer.prototype.rawLoadProjectModel = function (xmlNode) {
hidden
);
}
if (watcher) {
watcher.setStyle(model.attributes.style || 'normal');
if (watcher.style === 'slider') {
watcher.setSliderMin(model.attributes.min || '1');
watcher.setSliderMax(model.attributes.max || '100');
}
watcher.setPosition(
project.stage.topLeft().add(new Point(
+model.attributes.x || 0,
+model.attributes.y || 0
))
);
project.stage.add(watcher);
watcher.onNextStep = function () {this.currentValue = null; };
watcher.setStyle(model.attributes.style || 'normal');
if (watcher.style === 'slider') {
watcher.setSliderMin(model.attributes.min || '1', true);
watcher.setSliderMax(model.attributes.max || '100', true);
}
watcher.setPosition(
project.stage.topLeft().add(new Point(
+model.attributes.x || 0,
+model.attributes.y || 0
))
);
project.stage.add(watcher);
watcher.onNextStep = function () {this.currentValue = null; };
// set watcher's contentsMorph's extent if it is showing a list
// and if its monitor dimensions are given
if (watcher.currentValue instanceof List) {
extX = model.attributes.extX;
if (extX) {
watcher.cellMorph.contentsMorph.setWidth(+extX);
}
extY = model.attributes.extY;
if (extY) {
watcher.cellMorph.contentsMorph.setHeight(+extY);
}
// adjust my contentsMorph's handle position
watcher.cellMorph.contentsMorph.handle.drawNew();
// set watcher's contentsMorph's extent if it is showing a list and
// its monitor dimensions are given
if (watcher.currentValue instanceof List) {
extX = model.attributes.extX;
if (extX) {
watcher.cellMorph.contentsMorph.setWidth(+extX);
}
extY = model.attributes.extY;
if (extY) {
watcher.cellMorph.contentsMorph.setHeight(+extY);
}
// adjust my contentsMorph's handle position
watcher.cellMorph.contentsMorph.handle.drawNew();
}
});
this.objects = {};
@ -647,9 +650,17 @@ SnapSerializer.prototype.loadSprites = function (xmlString, ide) {
myself.loadObject(sprite, model);
});
// restore nesting associations
// restore inheritance and nesting associations
project.stage.children.forEach(function (sprite) {
var anchor;
var exemplar, anchor;
if (sprite.inheritanceInfo) { // only sprites can inherit
exemplar = project.sprites[
sprite.inheritanceInfo.exemplar
];
if (exemplar) {
sprite.setExemplar(exemplar);
}
}
if (sprite.nestingInfo) { // only sprites may have nesting info
anchor = project.sprites[sprite.nestingInfo.anchor];
if (anchor) {
@ -659,6 +670,7 @@ SnapSerializer.prototype.loadSprites = function (xmlString, ide) {
}
});
project.stage.children.forEach(function (sprite) {
delete sprite.inheritanceInfo;
if (sprite.nestingInfo) { // only sprites may have nesting info
sprite.nestingScale = +(sprite.nestingInfo.scale || sprite.scale);
delete sprite.nestingInfo;
@ -707,6 +719,14 @@ SnapSerializer.prototype.loadObject = function (object, model) {
this.loadScripts(object.scripts, model.require('scripts'));
};
SnapSerializer.prototype.loadInheritanceInfo = function (object, model) {
// private
var info = model.childNamed('inherit');
if (info) {
object.inheritanceInfo = info.attributes;
}
};
SnapSerializer.prototype.loadNestingInfo = function (object, model) {
// private
var info = model.childNamed('nest');
@ -1416,6 +1436,7 @@ StageMorph.prototype.toXML = function (serializer) {
'costume="@" tempo="@" threadsafe="@" ' +
'lines="@" ' +
'codify="@" ' +
'inheritance="@" ' +
'scheduled="@" ~>' +
'<pentrails>$</pentrails>' +
'<costumes>%</costumes>' +
@ -1443,6 +1464,7 @@ StageMorph.prototype.toXML = function (serializer) {
this.isThreadSafe,
SpriteMorph.prototype.useFlatLineEnds ? 'flat' : 'round',
this.enableCodeMapping,
this.enableInheritance,
StageMorph.prototype.frameRate !== 0,
this.trailsCanvas.toDataURL('image/png'),
serializer.store(this.costumes, this.name + '_cst'),
@ -1475,6 +1497,7 @@ SpriteMorph.prototype.toXML = function (serializer) {
' draggable="@"' +
'%' +
' costume="@" color="@,@,@" pen="@" ~>' +
'%' + // inheritance info
'%' + // nesting info
'<costumes>%</costumes>' +
'<sounds>%</sounds>' +
@ -1497,6 +1520,13 @@ SpriteMorph.prototype.toXML = function (serializer) {
this.color.b,
this.penPoint,
// inheritance info
this.exemplar
? '<inherit exemplar="' +
this.exemplar.name
+ '"/>'
: '',
// nesting info
this.anchor
? '<nest anchor="' +

Wyświetl plik

@ -83,7 +83,7 @@ ArgLabelMorph, localize, XML_Element, hex_sha512*/
// Global stuff ////////////////////////////////////////////////////////
modules.threads = '2015-June-25';
modules.threads = '2015-July-27';
var ThreadManager;
var Process;
@ -1157,7 +1157,8 @@ Process.prototype.doSetVar = function (varName, value) {
if (name.expression.selector === 'reportGetVar') {
name.variables.setVar(
name.expression.blockSpec,
value
value,
this.blockReceiver()
);
return;
}
@ -1173,7 +1174,8 @@ Process.prototype.doChangeVar = function (varName, value) {
if (name.expression.selector === 'reportGetVar') {
name.variables.changeVar(
name.expression.blockSpec,
value
value,
this.blockReceiver()
);
return;
}
@ -1206,7 +1208,8 @@ Process.prototype.doShowVar = function (varName) {
if (this.homeContext.receiver) {
stage = this.homeContext.receiver.parentThatIsA(StageMorph);
if (stage) {
target = varFrame.find(name);
target = varFrame.silentFind(name);
if (!target) {return; }
// first try to find an existing (hidden) watcher
watcher = detect(
stage.children,
@ -1223,7 +1226,7 @@ Process.prototype.doShowVar = function (varName) {
}
// if no watcher exists, create a new one
isGlobal = contains(
this.homeContext.receiver.variables.parentFrame.names(),
this.homeContext.receiver.globalVariables().names(),
varName
);
if (isGlobal || target.owner) {
@ -1302,6 +1305,23 @@ Process.prototype.doRemoveTemporaries = function () {
}
};
// Process sprite inheritance primitives
Process.prototype.doDeleteAttr = function (attrName) {
// currently only variables are deletable
var name = attrName,
rcvr = this.blockReceiver();
if (name instanceof Context) {
if (name.expression.selector === 'reportGetVar') {
name = name.expression.blockSpec;
}
}
if (contains(rcvr.inheritedVariableNames(true), name)) {
rcvr.deleteVariable(name);
}
};
// Process lists primitives
Process.prototype.reportNewList = function (elements) {
@ -3115,35 +3135,50 @@ VariableFrame.prototype.silentFind = function (name) {
return null;
};
VariableFrame.prototype.setVar = function (name, value) {
/*
change the specified variable if it exists
else throw an error, because variables need to be
declared explicitly (e.g. through a "script variables" block),
before they can be accessed.
*/
VariableFrame.prototype.setVar = function (name, value, sender) {
// change the specified variable if it exists
// else throw an error, because variables need to be
// declared explicitly (e.g. through a "script variables" block),
// before they can be accessed.
// if the found frame is inherited by the sender sprite
// shadow it (create an explicit one for the sender)
// before setting the value ("create-on-write")
var frame = this.find(name);
if (frame) {
frame.vars[name].value = value;
if (sender instanceof SpriteMorph &&
(frame.owner instanceof SpriteMorph) &&
(sender !== frame.owner)) {
sender.shadowVar(name, value);
} else {
frame.vars[name].value = value;
}
}
};
VariableFrame.prototype.changeVar = function (name, delta) {
/*
change the specified variable if it exists
else throw an error, because variables need to be
declared explicitly (e.g. through a "script variables" block,
before they can be accessed.
*/
VariableFrame.prototype.changeVar = function (name, delta, sender) {
// change the specified variable if it exists
// else throw an error, because variables need to be
// declared explicitly (e.g. through a "script variables" block,
// before they can be accessed.
// if the found frame is inherited by the sender sprite
// shadow it (create an explicit one for the sender)
// before changing the value ("create-on-write")
var frame = this.find(name),
value;
value,
newValue;
if (frame) {
value = parseFloat(frame.vars[name].value);
if (isNaN(value)) {
frame.vars[name].value = delta;
newValue = isNaN(value) ? delta : value + parseFloat(delta);
if (sender instanceof SpriteMorph &&
(frame.owner instanceof SpriteMorph) &&
(sender !== frame.owner)) {
sender.shadowVar(name, newValue);
} else {
frame.vars[name].value = value + parseFloat(delta);
frame.vars[name].value = newValue;
}
}
};

File diff suppressed because one or more lines are too long

Wyświetl plik

@ -74,7 +74,7 @@ HTMLCanvasElement, fontHeight, SymbolMorph, localize, SpeechBubbleMorph,
ArrowMorph, MenuMorph, isString, isNil, SliderMorph, MorphicPreferences,
ScrollFrameMorph*/
modules.widgets = '2015-June-25';
modules.widgets = '2015-July-27';
var PushButtonMorph;
var ToggleButtonMorph;
@ -560,12 +560,13 @@ ToggleButtonMorph.prototype.init = function (
// ToggleButtonMorph events
ToggleButtonMorph.prototype.mouseEnter = function () {
var contents = this.hint instanceof Function ? this.hint() : this.hint;
if (!this.state) {
this.image = this.highlightImage;
this.changed();
}
if (this.hint) {
this.bubbleHelp(this.hint);
if (contents) {
this.bubbleHelp(contents);
}
};