kopia lustrzana https://github.com/backface/turtlestitch
give up on #open:
Works for #run, but #open is too hard (because it can open things other than projects).pull/29/head
rodzic
f14a7cf3e2
commit
3c062b4540
531
gui.js
531
gui.js
|
@ -68,11 +68,11 @@ fontHeight, hex_sha512, sb, CommentMorph, CommandBlockMorph,
|
|||
BlockLabelPlaceHolderMorph, Audio, SpeechBubbleMorph, ScriptFocusMorph,
|
||||
XML_Element, WatcherMorph, BlockRemovalDialogMorph, saveAs, TableMorph,
|
||||
isSnapObject, isRetinaEnabled, disableRetinaSupport, enableRetinaSupport,
|
||||
isRetinaSupported, SliderMorph, Animation*/
|
||||
isRetinaSupported, SliderMorph*/
|
||||
|
||||
// Global stuff ////////////////////////////////////////////////////////
|
||||
|
||||
modules.gui = '2016-December-27';
|
||||
modules.gui = '2016-November-10';
|
||||
|
||||
// Declarations
|
||||
|
||||
|
@ -327,7 +327,6 @@ IDE_Morph.prototype.openIn = function (world) {
|
|||
this.inform('Snap!', motd);
|
||||
}
|
||||
*/
|
||||
|
||||
function interpretUrlAnchors() {
|
||||
var dict;
|
||||
function doDictFlags() {
|
||||
|
@ -343,10 +342,8 @@ IDE_Morph.prototype.openIn = function (world) {
|
|||
|
||||
if (dict.hideControls) {
|
||||
myself.controlBar.hide();
|
||||
window.onbeforeunload = nop;
|
||||
}
|
||||
if (dict.noExitWarning) {
|
||||
window.onbeforeunload = nop;
|
||||
myself.toggleAppMode(true);
|
||||
window.onbeforeunload = function () {nop(); };
|
||||
}
|
||||
};
|
||||
if (location.hash.substr(0, 6) === '#open:') {
|
||||
|
@ -369,7 +366,8 @@ IDE_Morph.prototype.openIn = function (world) {
|
|||
}
|
||||
} else if (location.hash.substr(0, 5) === '#run:') {
|
||||
hash = location.hash.substr(5);
|
||||
hash = hash.slice(0,hash.indexOf("&"));
|
||||
idx = hash.indexOf("&");
|
||||
if (idx > 0) {hash = hash.slice(0,idx);}
|
||||
if (hash.charAt(0) === '%'
|
||||
|| hash.search(/\%(?:[0-9a-f]{2})/i) > -1) {
|
||||
hash = decodeURIComponent(hash);
|
||||
|
@ -381,7 +379,6 @@ IDE_Morph.prototype.openIn = function (world) {
|
|||
}
|
||||
this.toggleAppMode(true);
|
||||
dict = SnapCloud.parseDict(location.hash.substr(5));
|
||||
|
||||
doDictFlags();
|
||||
} else if (location.hash.substr(0, 9) === '#present:') {
|
||||
this.shield = new Morph();
|
||||
|
@ -417,7 +414,8 @@ IDE_Morph.prototype.openIn = function (world) {
|
|||
myself.shield.destroy();
|
||||
myself.shield = null;
|
||||
msg.destroy();
|
||||
|
||||
|
||||
myself.toggleAppMode(true);
|
||||
doDictFlags();
|
||||
}
|
||||
]);
|
||||
|
@ -464,20 +462,6 @@ IDE_Morph.prototype.openIn = function (world) {
|
|||
},
|
||||
this.cloudError()
|
||||
);
|
||||
} else if (location.hash.substr(0, 4) === '#dl:') {
|
||||
myself.showMessage('Fetching project\nfrom the cloud...');
|
||||
|
||||
// make sure to lowercase the username
|
||||
dict = SnapCloud.parseDict(location.hash.substr(4));
|
||||
dict.Username = dict.Username.toLowerCase();
|
||||
|
||||
SnapCloud.getPublicProject(
|
||||
SnapCloud.encodeDict(dict),
|
||||
function (projectData) {
|
||||
window.open('data:text/xml,' + projectData);
|
||||
},
|
||||
this.cloudError()
|
||||
);
|
||||
} else if (location.hash.substr(0, 6) === '#lang:') {
|
||||
urlLanguage = location.hash.substr(6);
|
||||
this.setLanguage(urlLanguage);
|
||||
|
@ -1047,7 +1031,7 @@ IDE_Morph.prototype.createPalette = function (forSearching) {
|
|||
this.palette.enableAutoScrolling = false;
|
||||
this.palette.contents.acceptsDrops = false;
|
||||
|
||||
this.palette.reactToDropOf = function (droppedMorph, hand) {
|
||||
this.palette.reactToDropOf = function (droppedMorph) {
|
||||
if (droppedMorph instanceof DialogBoxMorph) {
|
||||
myself.world().add(droppedMorph);
|
||||
} else if (droppedMorph instanceof SpriteMorph) {
|
||||
|
@ -1057,22 +1041,8 @@ IDE_Morph.prototype.createPalette = function (forSearching) {
|
|||
myself.removeSprite(droppedMorph.object);
|
||||
} else if (droppedMorph instanceof CostumeIconMorph) {
|
||||
myself.currentSprite.wearCostume(null);
|
||||
droppedMorph.perish();
|
||||
} else if (droppedMorph instanceof BlockMorph) {
|
||||
if (hand && hand.grabOrigin.origin instanceof ScriptsMorph) {
|
||||
hand.grabOrigin.origin.clearDropInfo();
|
||||
hand.grabOrigin.origin.lastDroppedBlock = droppedMorph;
|
||||
hand.grabOrigin.origin.recordDrop(hand.grabOrigin);
|
||||
}
|
||||
droppedMorph.perish();
|
||||
droppedMorph.destroy();
|
||||
} else {
|
||||
droppedMorph.perish();
|
||||
}
|
||||
};
|
||||
|
||||
this.palette.contents.reactToDropOf = function (droppedMorph) {
|
||||
// for "undrop" operation
|
||||
if (droppedMorph instanceof BlockMorph) {
|
||||
droppedMorph.destroy();
|
||||
}
|
||||
};
|
||||
|
@ -1290,9 +1260,7 @@ IDE_Morph.prototype.createSpriteBar = function () {
|
|||
tabColors,
|
||||
null, // target
|
||||
function () {tabBar.tabTo('costumes'); },
|
||||
localize(this.currentSprite instanceof SpriteMorph ?
|
||||
'Costumes' : 'Backgrounds'
|
||||
),
|
||||
localize('Costumes'), // label
|
||||
function () { // query
|
||||
return myself.currentTab === 'costumes';
|
||||
}
|
||||
|
@ -1365,7 +1333,6 @@ IDE_Morph.prototype.createSpriteEditor = function () {
|
|||
this.spriteEditor.contents.acceptsDrops = true;
|
||||
|
||||
scripts.scrollFrame = this.spriteEditor;
|
||||
scripts.updateUndropControls();
|
||||
this.add(this.spriteEditor);
|
||||
this.spriteEditor.scrollX(this.spriteEditor.padding);
|
||||
this.spriteEditor.scrollY(this.spriteEditor.padding);
|
||||
|
@ -1621,13 +1588,10 @@ IDE_Morph.prototype.fixLayout = function (situation) {
|
|||
this.stage.setScale(this.isSmallStage ? this.stageRatio : 1);
|
||||
this.stage.setTop(this.logo.bottom() + padding);
|
||||
this.stage.setRight(this.right());
|
||||
maxPaletteWidth = Math.max(
|
||||
200,
|
||||
this.width() -
|
||||
this.stage.width() -
|
||||
this.spriteBar.tabBar.width() -
|
||||
(this.padding * 2)
|
||||
);
|
||||
maxPaletteWidth = this.width() -
|
||||
this.stage.width() -
|
||||
this.spriteBar.tabBar.width() -
|
||||
(this.padding * 2);
|
||||
if (this.paletteWidth > maxPaletteWidth) {
|
||||
this.paletteWidth = maxPaletteWidth;
|
||||
this.fixLayout();
|
||||
|
@ -1991,8 +1955,7 @@ IDE_Morph.prototype.applySavedSettings = function () {
|
|||
plainprototype = this.getSetting('plainprototype'),
|
||||
keyboard = this.getSetting('keyboard'),
|
||||
tables = this.getSetting('tables'),
|
||||
tableLines = this.getSetting('tableLines'),
|
||||
autoWrapping = this.getSetting('autowrapping');
|
||||
tableLines = this.getSetting('tableLines');
|
||||
|
||||
// design
|
||||
if (design === 'flat') {
|
||||
|
@ -2053,13 +2016,6 @@ IDE_Morph.prototype.applySavedSettings = function () {
|
|||
TableMorph.prototype.highContrast = false;
|
||||
}
|
||||
|
||||
// nested auto-wrapping
|
||||
if (autoWrapping === 'false') {
|
||||
ScriptsMorph.prototype.enableNestedAutoWrapping = false;
|
||||
} else {
|
||||
ScriptsMorph.prototype.enableNestedAutoWrapping = true;
|
||||
}
|
||||
|
||||
// plain prototype labels
|
||||
if (plainprototype) {
|
||||
BlockLabelPlaceHolderMorph.prototype.plainLabel = true;
|
||||
|
@ -2418,20 +2374,6 @@ IDE_Morph.prototype.settingsMenu = function () {
|
|||
);
|
||||
}
|
||||
menu.addLine();
|
||||
/*
|
||||
addPreference(
|
||||
'JavaScript',
|
||||
function () {
|
||||
Process.prototype.enableJS = !Process.prototype.enableJS;
|
||||
myself.currentSprite.blocksCache.operators = null;
|
||||
myself.currentSprite.paletteCache.operators = null;
|
||||
myself.refreshPalette();
|
||||
},
|
||||
Process.prototype.enableJS,
|
||||
'uncheck to disable support for\nnative JavaScript functions',
|
||||
'check to support\nnative JavaScript functions'
|
||||
);
|
||||
*/
|
||||
if (isRetinaSupported()) {
|
||||
addPreference(
|
||||
'Retina display support',
|
||||
|
@ -2507,7 +2449,7 @@ IDE_Morph.prototype.settingsMenu = function () {
|
|||
'Execute on slider change',
|
||||
'toggleSliderExecute',
|
||||
ArgMorph.prototype.executeOnSliderEdit,
|
||||
'uncheck to suppress\nrunning scripts\nwhen moving the slider',
|
||||
'uncheck to supress\nrunning scripts\nwhen moving the slider',
|
||||
'check to run\nthe edited script\nwhen moving the slider'
|
||||
);
|
||||
}
|
||||
|
@ -2575,22 +2517,6 @@ IDE_Morph.prototype.settingsMenu = function () {
|
|||
'check for alternative\nGUI design',
|
||||
false
|
||||
);
|
||||
addPreference(
|
||||
'Nested auto-wrapping',
|
||||
function () {
|
||||
ScriptsMorph.prototype.enableNestedAutoWrapping =
|
||||
!ScriptsMorph.prototype.enableNestedAutoWrapping;
|
||||
if (ScriptsMorph.prototype.enableNestedAutoWrapping) {
|
||||
myself.removeSetting('autowrapping');
|
||||
} else {
|
||||
myself.saveSetting('autowrapping', false);
|
||||
}
|
||||
},
|
||||
ScriptsMorph.prototype.enableNestedAutoWrapping,
|
||||
'uncheck to confine auto-wrapping\nto top-level block stacks',
|
||||
'check to enable auto-wrapping\ninside nested block stacks',
|
||||
false
|
||||
);
|
||||
addPreference(
|
||||
'Project URLs',
|
||||
function () {
|
||||
|
@ -2713,8 +2639,7 @@ IDE_Morph.prototype.settingsMenu = function () {
|
|||
'toggleVariableFrameRate',
|
||||
StageMorph.prototype.frameRate,
|
||||
'uncheck for greater speed\nat variable frame rates',
|
||||
'check for smooth, predictable\nanimations across computers',
|
||||
true
|
||||
'check for smooth, predictable\nanimations across computers'
|
||||
);
|
||||
addPreference(
|
||||
'Flat line ends',
|
||||
|
@ -2777,28 +2702,24 @@ IDE_Morph.prototype.projectMenu = function () {
|
|||
'Costumes' : 'Backgrounds',
|
||||
shiftClicked = (world.currentKey === 16);
|
||||
|
||||
function createMediaMenu(folderName, loadFunction) {
|
||||
// Utility for creating Libraries, etc menus.
|
||||
// loadFunction takes in two parameters:
|
||||
// a file URL, and a canonical name
|
||||
// Utility for creating Costumes, etc menus.
|
||||
// loadFunction takes in two parameters: a file URL, and a canonical name
|
||||
function createMediaMenu(mediaType, loadFunction) {
|
||||
return function () {
|
||||
myself.getMediaList(
|
||||
folderName,
|
||||
function (names) {
|
||||
var mediaMenu = new MenuMorph(
|
||||
myself,
|
||||
localize('Import') + ' ' + localize(folderName)
|
||||
);
|
||||
names.forEach(function (item) {
|
||||
mediaMenu.addItem(
|
||||
item.name,
|
||||
function () {loadFunction(item.file, item.name); },
|
||||
item.help
|
||||
);
|
||||
});
|
||||
mediaMenu.popup(world, pos);
|
||||
}
|
||||
);
|
||||
var names = this.getMediaList(mediaType),
|
||||
mediaMenu = new MenuMorph(
|
||||
myself,
|
||||
localize('Import') + ' ' + localize(mediaType)
|
||||
);
|
||||
|
||||
names.forEach(function (item) {
|
||||
mediaMenu.addItem(
|
||||
item.name,
|
||||
function () {loadFunction(item.file, item.name); },
|
||||
item.help
|
||||
);
|
||||
});
|
||||
mediaMenu.popup(world, pos);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -2923,11 +2844,9 @@ IDE_Morph.prototype.projectMenu = function () {
|
|||
menu.addItem(
|
||||
'Import tools',
|
||||
function () {
|
||||
myself.getURL(
|
||||
myself.resourceURL('tools.xml'),
|
||||
function (txt) {
|
||||
myself.droppedText(txt, 'tools');
|
||||
}
|
||||
myself.droppedText(
|
||||
myself.getURL(myself.resourceURL('tools.xml')),
|
||||
'tools'
|
||||
);
|
||||
},
|
||||
'load the official library of\npowerful blocks'
|
||||
|
@ -2936,13 +2855,9 @@ IDE_Morph.prototype.projectMenu = function () {
|
|||
'Libraries...',
|
||||
createMediaMenu(
|
||||
'libraries',
|
||||
function (file, name) {
|
||||
myself.getURL(
|
||||
myself.resourceURL('libraries', file),
|
||||
function (txt) {
|
||||
myself.droppedText(txt, name);
|
||||
}
|
||||
);
|
||||
function loadLib(file, name) {
|
||||
var url = myself.resourceURL('libraries', file);
|
||||
myself.droppedText(myself.getURL(url), name);
|
||||
}
|
||||
),
|
||||
'Select categories of additional blocks to add to this project.'
|
||||
|
@ -2957,9 +2872,16 @@ IDE_Morph.prototype.projectMenu = function () {
|
|||
);
|
||||
menu.addItem(
|
||||
localize('Sounds') + '...',
|
||||
function () {
|
||||
myself.importMedia('Sounds');
|
||||
},
|
||||
createMediaMenu(
|
||||
'Sounds',
|
||||
function loadSound(file, name) {
|
||||
var url = myself.resourceURL('Sounds', file),
|
||||
audio = new Audio();
|
||||
audio.src = url;
|
||||
audio.load();
|
||||
myself.droppedAudio(audio, name);
|
||||
}
|
||||
),
|
||||
'Select a sound from the media library'
|
||||
);
|
||||
|
||||
|
@ -2974,34 +2896,18 @@ IDE_Morph.prototype.resourceURL = function () {
|
|||
return args.join('/');
|
||||
};
|
||||
|
||||
IDE_Morph.prototype.getMediaList = function (dirname, callback) {
|
||||
// Invoke the given callback with a list of files in a directory
|
||||
// based on the contents file.
|
||||
// If no callback is specified, synchronously return the list of files
|
||||
// Note: Synchronous fetching has been deprecated and should be switched
|
||||
var url = this.resourceURL(dirname, dirname.toUpperCase()),
|
||||
async = callback instanceof Function,
|
||||
myself = this,
|
||||
data;
|
||||
IDE_Morph.prototype.getMediaList = function (dirname) {
|
||||
// Return a list of files in a directory based on the contents file
|
||||
var url, data;
|
||||
|
||||
function alphabetically(x, y) {
|
||||
url = this.resourceURL(dirname, dirname.toUpperCase());
|
||||
data = this.parseResourceFile(this.getURL(url));
|
||||
|
||||
data.sort(function (x, y) {
|
||||
return x.name.toLowerCase() < y.name.toLowerCase() ? -1 : 1;
|
||||
}
|
||||
});
|
||||
|
||||
if (async) {
|
||||
this.getURL(
|
||||
url,
|
||||
function (txt) {
|
||||
var data = myself.parseResourceFile(txt);
|
||||
data.sort(alphabetically);
|
||||
callback.call(this, data);
|
||||
}
|
||||
);
|
||||
} else {
|
||||
data = this.parseResourceFile(this.getURL(url));
|
||||
data.sort(alphabetically);
|
||||
return data;
|
||||
}
|
||||
return data;
|
||||
};
|
||||
|
||||
IDE_Morph.prototype.parseResourceFile = function (text) {
|
||||
|
@ -3040,28 +2946,15 @@ IDE_Morph.prototype.parseResourceFile = function (text) {
|
|||
return items;
|
||||
};
|
||||
|
||||
IDE_Morph.prototype.importMedia = function (folderName) {
|
||||
IDE_Morph.prototype.importMedia = function (mediaType) {
|
||||
// open a dialog box letting the user browse available "built-in"
|
||||
// costumes, backgrounds or sounds
|
||||
var myself = this,
|
||||
msg = this.showMessage('Opening ' + folderName + '...');
|
||||
this.getMediaList(
|
||||
folderName,
|
||||
function (items) {
|
||||
msg.destroy();
|
||||
myself.popupMediaImportDialog(folderName, items);
|
||||
}
|
||||
);
|
||||
// costumes or backgrounds
|
||||
|
||||
};
|
||||
|
||||
IDE_Morph.prototype.popupMediaImportDialog = function (folderName, items) {
|
||||
// private - this gets called by importMedia() and creates
|
||||
// the actual dialog
|
||||
var dialog = new DialogBoxMorph().withKey('import' + folderName),
|
||||
var dialog = new DialogBoxMorph().withKey('import' + mediaType),
|
||||
frame = new ScrollFrameMorph(),
|
||||
selectedIcon = null,
|
||||
turtle = new SymbolMorph('turtle', 60),
|
||||
items = this.getMediaList(mediaType),
|
||||
myself = this,
|
||||
world = this.world(),
|
||||
handle;
|
||||
|
@ -3070,7 +2963,7 @@ IDE_Morph.prototype.popupMediaImportDialog = function (folderName, items) {
|
|||
frame.contents.acceptsDrops = false;
|
||||
frame.color = myself.groupColor;
|
||||
frame.fixLayout = nop;
|
||||
dialog.labelString = folderName;
|
||||
dialog.labelString = mediaType;
|
||||
dialog.createLabel();
|
||||
dialog.addBody(frame);
|
||||
dialog.addButton('ok', 'Import');
|
||||
|
@ -3078,22 +2971,10 @@ IDE_Morph.prototype.popupMediaImportDialog = function (folderName, items) {
|
|||
|
||||
dialog.ok = function () {
|
||||
if (selectedIcon) {
|
||||
if (selectedIcon.object instanceof Sound) {
|
||||
myself.droppedAudio(
|
||||
selectedIcon.object.copy().audio,
|
||||
selectedIcon.labelString
|
||||
);
|
||||
} else if (selectedIcon.object instanceof SVG_Costume) {
|
||||
myself.droppedSVG(
|
||||
selectedIcon.object.contents,
|
||||
selectedIcon.labelString
|
||||
);
|
||||
} else {
|
||||
myself.droppedImage(
|
||||
selectedIcon.object.contents,
|
||||
selectedIcon.labelString
|
||||
);
|
||||
}
|
||||
myself.droppedImage(
|
||||
selectedIcon.object.contents,
|
||||
selectedIcon.labelString
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -3129,70 +3010,31 @@ IDE_Morph.prototype.popupMediaImportDialog = function (folderName, items) {
|
|||
};
|
||||
|
||||
items.forEach(function (item) {
|
||||
// Caution: creating very many thumbnails can take a long time!
|
||||
var url = myself.resourceURL(folderName, item.file),
|
||||
var url = myself.resourceURL(mediaType, item.file),
|
||||
img = new Image(),
|
||||
suffix = url.slice(url.lastIndexOf('.') + 1).toLowerCase(),
|
||||
isSVG = suffix === 'svg' && !MorphicPreferences.rasterizeSVGs,
|
||||
isSound = contains(['wav', 'mp3'], suffix),
|
||||
cstTemplate,
|
||||
sndTemplate,
|
||||
icon;
|
||||
|
||||
if (isSound) {
|
||||
sndTemplate = icon = new SoundIconMorph(
|
||||
new Sound(new Audio(), item.name),
|
||||
sndTemplate
|
||||
icon = new CostumeIconMorph(
|
||||
new Costume(turtle.image, item.name)
|
||||
);
|
||||
} else {
|
||||
cstTemplate = icon = new CostumeIconMorph(
|
||||
new Costume(turtle.image, item.name),
|
||||
cstTemplate
|
||||
);
|
||||
}
|
||||
icon.isDraggable = false;
|
||||
icon.userMenu = nop;
|
||||
icon.action = function () {
|
||||
if (selectedIcon === icon) {return; }
|
||||
if (selectedIcon === icon) return;
|
||||
var prevSelected = selectedIcon;
|
||||
selectedIcon = icon;
|
||||
if (prevSelected) {prevSelected.refresh(); }
|
||||
if (prevSelected) prevSelected.refresh();
|
||||
};
|
||||
icon.doubleClickAction = dialog.ok;
|
||||
icon.query = function () {
|
||||
return icon === selectedIcon;
|
||||
};
|
||||
frame.addContents(icon);
|
||||
if (isSound) {
|
||||
icon.object.audio.onloadeddata = function () {
|
||||
icon.createThumbnail();
|
||||
icon.fixLayout();
|
||||
icon.refresh();
|
||||
};
|
||||
|
||||
icon.object.audio.src = url;
|
||||
icon.object.audio.load();
|
||||
} else if (isSVG) {
|
||||
img.onload = function () {
|
||||
icon.object = new SVG_Costume(img, item.name);
|
||||
icon.refresh();
|
||||
};
|
||||
myself.getURL(
|
||||
url,
|
||||
function (txt) {
|
||||
img.src = 'data:image/svg+xml;utf8,' +
|
||||
encodeURIComponent(txt);
|
||||
}
|
||||
);
|
||||
} else {
|
||||
img.onload = function () {
|
||||
var canvas = newCanvas(new Point(img.width, img.height), true);
|
||||
canvas.getContext('2d').drawImage(img, 0, 0);
|
||||
icon.object = new Costume(canvas, item.name);
|
||||
icon.refresh();
|
||||
};
|
||||
img.src = url;
|
||||
}
|
||||
img.onload = function () {
|
||||
var canvas = newCanvas(new Point(img.width, img.height), true);
|
||||
canvas.getContext('2d').drawImage(img, 0, 0);
|
||||
icon.object = new Costume(canvas, item.name);
|
||||
icon.refresh();
|
||||
};
|
||||
img.src = url;
|
||||
});
|
||||
dialog.popUp(world);
|
||||
dialog.setExtent(new Point(400, 300));
|
||||
|
@ -3215,7 +3057,7 @@ IDE_Morph.prototype.aboutSnap = function () {
|
|||
module, btn1, btn2, btn3, btn4, licenseBtn, translatorsBtn,
|
||||
world = this.world();
|
||||
|
||||
aboutTxt = 'Snap! 4.0.10 - dev -\nBuild Your Own Blocks\n\n'
|
||||
aboutTxt = 'Snap! 4.0.9.2\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'
|
||||
|
@ -3745,13 +3587,13 @@ IDE_Morph.prototype.exportProjectSummary = function (useDropShadows) {
|
|||
pname = this.projectName || localize('untitled');
|
||||
|
||||
html = new XML_Element('html');
|
||||
html.attributes.lang = SnapTranslator.language;
|
||||
// html.attributes.contenteditable = 'true';
|
||||
|
||||
head = addNode('head', html);
|
||||
|
||||
meta = addNode('meta', head);
|
||||
meta.attributes.charset = 'UTF-8';
|
||||
meta.attributes['http-equiv'] = 'Content-Type';
|
||||
meta.attributes.content = 'text/html; charset=UTF-8';
|
||||
|
||||
if (useDropShadows) {
|
||||
css = 'img {' +
|
||||
|
@ -3918,7 +3760,7 @@ IDE_Morph.prototype.exportProjectSummary = function (useDropShadows) {
|
|||
|
||||
this.saveFileAs(
|
||||
'<!DOCTYPE html>' + html.toString(),
|
||||
'text/html;charset=utf-8',
|
||||
'text/html;charset=utf-8,',
|
||||
pname,
|
||||
true // request opening a new window.
|
||||
);
|
||||
|
@ -4498,8 +4340,6 @@ IDE_Morph.prototype.toggleAppMode = function (appMode) {
|
|||
}
|
||||
});
|
||||
}
|
||||
// update undrop controls
|
||||
this.currentSprite.scripts.updateUndropControls();
|
||||
}
|
||||
this.setExtent(this.world().extent()); // resume trackChanges
|
||||
};
|
||||
|
@ -4507,7 +4347,6 @@ IDE_Morph.prototype.toggleAppMode = function (appMode) {
|
|||
IDE_Morph.prototype.toggleStageSize = function (isSmall, forcedRatio) {
|
||||
var myself = this,
|
||||
smallRatio = forcedRatio || 0.5,
|
||||
msecs = this.isAnimating ? 100 : 0,
|
||||
world = this.world(),
|
||||
shiftClicked = (world.currentKey === 16),
|
||||
altClicked = (world.currentKey === 18);
|
||||
|
@ -4517,23 +4356,25 @@ IDE_Morph.prototype.toggleStageSize = function (isSmall, forcedRatio) {
|
|||
}
|
||||
|
||||
function zoomTo(targetRatio) {
|
||||
var count = 1,
|
||||
steps = 5;
|
||||
myself.fps = 30;
|
||||
myself.isSmallStage = true;
|
||||
world.animations.push(new Animation(
|
||||
function (ratio) {
|
||||
myself.stageRatio = ratio;
|
||||
myself.setExtent(world.extent());
|
||||
},
|
||||
function () {
|
||||
return myself.stageRatio;
|
||||
},
|
||||
targetRatio - myself.stageRatio,
|
||||
msecs,
|
||||
null, // easing
|
||||
function () {
|
||||
myself.step = function () {
|
||||
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());
|
||||
};
|
||||
}
|
||||
|
||||
if (shiftClicked) {
|
||||
|
@ -4551,29 +4392,39 @@ IDE_Morph.prototype.toggleStageSize = function (isSmall, forcedRatio) {
|
|||
} else {
|
||||
toggle();
|
||||
}
|
||||
if (this.isSmallStage) {
|
||||
zoomTo(smallRatio);
|
||||
if (this.isAnimating) {
|
||||
if (this.isSmallStage) {
|
||||
zoomTo(smallRatio);
|
||||
} else {
|
||||
zoomTo(1);
|
||||
}
|
||||
} else {
|
||||
zoomTo(1);
|
||||
if (this.isSmallStage) {this.stageRatio = smallRatio; }
|
||||
this.setExtent(world.extent());
|
||||
}
|
||||
};
|
||||
|
||||
IDE_Morph.prototype.setPaletteWidth = function (newWidth) {
|
||||
var msecs = this.isAnimating ? 100 : 0,
|
||||
var count = 1,
|
||||
steps = this.isAnimating ? 5 : 1,
|
||||
world = this.world(),
|
||||
myself = this;
|
||||
|
||||
world.animations.push(new Animation(
|
||||
function (newWidth) {
|
||||
newWidth = Math.max(newWidth, 200);
|
||||
this.fps = 30;
|
||||
this.step = function () {
|
||||
var diff;
|
||||
if (count >= steps) {
|
||||
myself.paletteWidth = newWidth;
|
||||
myself.setExtent(world.extent());
|
||||
},
|
||||
function () {
|
||||
return myself.paletteWidth;
|
||||
},
|
||||
newWidth - myself.paletteWidth,
|
||||
msecs
|
||||
));
|
||||
delete myself.step;
|
||||
myself.fps = 0;
|
||||
} else {
|
||||
count += 1;
|
||||
diff = (myself.paletteWidth - newWidth) / 2;
|
||||
myself.paletteWidth -= diff;
|
||||
}
|
||||
myself.setExtent(world.extent());
|
||||
};
|
||||
};
|
||||
|
||||
IDE_Morph.prototype.createNewProject = function () {
|
||||
|
@ -5240,45 +5091,21 @@ IDE_Morph.prototype.setCloudURL = function () {
|
|||
);
|
||||
};
|
||||
|
||||
// IDE_Morph HTTP data fetching
|
||||
// IDE_Morph synchronous HTTP data fetching
|
||||
|
||||
IDE_Morph.prototype.getURL = function (url, callback) {
|
||||
// fetch the contents of a url and pass it into the specified callback.
|
||||
// If no callback is specified synchronously fetch and return it
|
||||
// Note: Synchronous fetching has been deprecated and should be switched
|
||||
IDE_Morph.prototype.getURL = function (url) {
|
||||
var request = new XMLHttpRequest(),
|
||||
async = callback instanceof Function,
|
||||
myself = this;
|
||||
try {
|
||||
request.open('GET', url, async);
|
||||
if (async) {
|
||||
request.onreadystatechange = function () {
|
||||
if (request.readyState === 4) {
|
||||
if (request.responseText) {
|
||||
callback.call(
|
||||
myself,
|
||||
request.responseText
|
||||
);
|
||||
} else {
|
||||
throw new Error('unable to retrieve ' + url);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
request.open('GET', url, false);
|
||||
request.send();
|
||||
if (!async) {
|
||||
if (request.status === 200) {
|
||||
return request.responseText;
|
||||
}
|
||||
throw new Error('unable to retrieve ' + url);
|
||||
}
|
||||
} catch (err) {
|
||||
myself.showMessage(err.toString());
|
||||
if (async) {
|
||||
callback.call(this);
|
||||
} else {
|
||||
if (request.status === 200) {
|
||||
return request.responseText;
|
||||
}
|
||||
throw new Error('unable to retrieve ' + url);
|
||||
} catch (err) {
|
||||
myself.showMessage(err.toString());
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -5349,8 +5176,6 @@ ProjectDialogMorph.prototype.init = function (ide, task) {
|
|||
this.handle = null;
|
||||
this.srcBar = null;
|
||||
this.nameField = null;
|
||||
this.filterField = null;
|
||||
this.magnifiyingGlass = null;
|
||||
this.listField = null;
|
||||
this.preview = null;
|
||||
this.notesText = null;
|
||||
|
@ -5407,7 +5232,6 @@ ProjectDialogMorph.prototype.buildContents = function () {
|
|||
this.addSourceButton('cloud', localize('Cloud'), 'cloud');
|
||||
this.addSourceButton('local', localize('Browser'), 'storage');
|
||||
if (this.task === 'open') {
|
||||
this.buildFilterField();
|
||||
this.addSourceButton('examples', localize('Examples'), 'poster');
|
||||
}
|
||||
this.srcBar.fixLayout();
|
||||
|
@ -5629,54 +5453,6 @@ ProjectDialogMorph.prototype.fixListFieldItemColors = function () {
|
|||
});
|
||||
};
|
||||
|
||||
// ProjectDialogMorph filter field
|
||||
|
||||
ProjectDialogMorph.prototype.buildFilterField = function () {
|
||||
var myself = this;
|
||||
|
||||
this.filterField = new InputFieldMorph('');
|
||||
this.magnifiyingGlass =
|
||||
new SymbolMorph(
|
||||
'magnifiyingGlass',
|
||||
this.filterField.height(),
|
||||
this.titleBarColor.darker(50));
|
||||
|
||||
this.body.add(this.magnifiyingGlass);
|
||||
this.body.add(this.filterField);
|
||||
|
||||
this.filterField.reactToKeystroke = function (evt) {
|
||||
var text = this.getValue();
|
||||
|
||||
myself.listField.elements =
|
||||
myself.projectList.filter(function (aProject) {
|
||||
var name,
|
||||
notes;
|
||||
|
||||
if (aProject.ProjectName) { // cloud
|
||||
name = aProject.ProjectName;
|
||||
notes = aProject.Notes;
|
||||
} else { // local or examples
|
||||
name = aProject.name;
|
||||
notes = aProject.notes || '';
|
||||
}
|
||||
|
||||
return name.toLowerCase().indexOf(text.toLowerCase()) > -1 ||
|
||||
notes.toLowerCase().indexOf(text.toLowerCase()) > -1;
|
||||
});
|
||||
|
||||
if (myself.listField.elements.length === 0) {
|
||||
myself.listField.elements.push('(no matches)');
|
||||
}
|
||||
|
||||
myself.clearDetails();
|
||||
myself.listField.buildListContents();
|
||||
myself.fixListFieldItemColors();
|
||||
myself.listField.adjustScrollBars();
|
||||
myself.listField.scrollY(myself.listField.top());
|
||||
myself.fixLayout();
|
||||
};
|
||||
};
|
||||
|
||||
// ProjectDialogMorph ops
|
||||
|
||||
ProjectDialogMorph.prototype.setSource = function (source) {
|
||||
|
@ -5718,7 +5494,7 @@ ProjectDialogMorph.prototype.setSource = function (source) {
|
|||
this.projectList,
|
||||
this.projectList.length > 0 ?
|
||||
function (element) {
|
||||
return element.name || element;
|
||||
return element.name;
|
||||
} : null,
|
||||
null,
|
||||
function () {myself.ok(); }
|
||||
|
@ -5836,7 +5612,7 @@ ProjectDialogMorph.prototype.installCloudProjectList = function (pl) {
|
|||
this.projectList,
|
||||
this.projectList.length > 0 ?
|
||||
function (element) {
|
||||
return element.ProjectName || element;
|
||||
return element.ProjectName;
|
||||
} : null,
|
||||
[ // format: display shared project names bold
|
||||
[
|
||||
|
@ -6192,8 +5968,6 @@ ProjectDialogMorph.prototype.unshareProject = function () {
|
|||
ProjectDialogMorph.prototype.edit = function () {
|
||||
if (this.nameField) {
|
||||
this.nameField.edit();
|
||||
} else if (this.filterField) {
|
||||
this.filterField.edit();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -6202,7 +5976,6 @@ ProjectDialogMorph.prototype.edit = function () {
|
|||
ProjectDialogMorph.prototype.fixLayout = function () {
|
||||
var th = fontHeight(this.titleFontSize) + this.titlePadding * 2,
|
||||
thin = this.padding / 2,
|
||||
inputField = this.nameField || this.filterField,
|
||||
oldFlag = Morph.prototype.trackChanges;
|
||||
|
||||
Morph.prototype.trackChanges = false;
|
||||
|
@ -6221,13 +5994,14 @@ ProjectDialogMorph.prototype.fixLayout = function () {
|
|||
this.height() - this.padding * 3 - th - this.buttons.height()
|
||||
));
|
||||
this.srcBar.setPosition(this.body.position());
|
||||
|
||||
inputField.setWidth(
|
||||
if (this.nameField) {
|
||||
this.nameField.setWidth(
|
||||
this.body.width() - this.srcBar.width() - this.padding * 6
|
||||
);
|
||||
inputField.setLeft(this.srcBar.right() + this.padding * 3);
|
||||
inputField.setTop(this.srcBar.top());
|
||||
inputField.drawNew();
|
||||
this.nameField.setLeft(this.srcBar.right() + this.padding * 3);
|
||||
this.nameField.setTop(this.srcBar.top());
|
||||
this.nameField.drawNew();
|
||||
}
|
||||
|
||||
this.listField.setLeft(this.srcBar.right() + this.padding);
|
||||
this.listField.setWidth(
|
||||
|
@ -6239,18 +6013,22 @@ ProjectDialogMorph.prototype.fixLayout = function () {
|
|||
);
|
||||
this.listField.contents.children[0].adjustWidths();
|
||||
|
||||
this.listField.setTop(inputField.bottom() + this.padding);
|
||||
this.listField.setHeight(
|
||||
this.body.height() - inputField.height() - this.padding
|
||||
);
|
||||
|
||||
if (this.magnifiyingGlass) {
|
||||
this.magnifiyingGlass.setTop(inputField.top());
|
||||
this.magnifiyingGlass.setLeft(this.listField.left());
|
||||
if (this.nameField) {
|
||||
this.listField.setTop(this.nameField.bottom() + this.padding);
|
||||
this.listField.setHeight(
|
||||
this.body.height() - this.nameField.height() - this.padding
|
||||
);
|
||||
} else {
|
||||
this.listField.setTop(this.body.top());
|
||||
this.listField.setHeight(this.body.height());
|
||||
}
|
||||
|
||||
this.preview.setRight(this.body.right());
|
||||
this.preview.setTop(inputField.bottom() + this.padding);
|
||||
if (this.nameField) {
|
||||
this.preview.setTop(this.nameField.bottom() + this.padding);
|
||||
} else {
|
||||
this.preview.setTop(this.body.top());
|
||||
}
|
||||
|
||||
this.notesField.setTop(this.preview.bottom() + thin);
|
||||
this.notesField.setLeft(this.preview.left());
|
||||
|
@ -6849,8 +6627,7 @@ CostumeIconMorph.prototype.renameCostume = function () {
|
|||
}
|
||||
}
|
||||
).prompt(
|
||||
this.currentSprite instanceof SpriteMorph ?
|
||||
'rename costume' : 'rename background',
|
||||
'rename costume',
|
||||
costume.name,
|
||||
this.world()
|
||||
);
|
||||
|
|
Ładowanie…
Reference in New Issue