summaryrefslogtreecommitdiff
path: root/gui.js
diff options
context:
space:
mode:
Diffstat (limited to 'gui.js')
-rw-r--r--gui.js135
1 files changed, 111 insertions, 24 deletions
diff --git a/gui.js b/gui.js
index 6af9137..44b0f62 100644
--- a/gui.js
+++ b/gui.js
@@ -69,7 +69,7 @@ SpeechBubbleMorph*/
// Global stuff ////////////////////////////////////////////////////////
-modules.gui = '2014-July-30';
+modules.gui = '2014-December-04';
// Declarations
@@ -185,7 +185,7 @@ IDE_Morph.prototype.init = function (isAutoFill) {
MorphicPreferences.globalFontFamily = 'Helvetica, Arial';
// restore saved user preferences
- this.userLanguage = null; // user language preference for startup
+ this.userLanguage = null;
this.applySavedSettings();
// additional properties:
@@ -212,6 +212,7 @@ IDE_Morph.prototype.init = function (isAutoFill) {
this.corral = null;
this.isAutoFill = isAutoFill || true;
+ this.isMuted = false;
this.isAppMode = false;
this.isSmallStage = false;
this.filePicker = null;
@@ -233,10 +234,6 @@ IDE_Morph.prototype.init = function (isAutoFill) {
IDE_Morph.prototype.openIn = function (world) {
var hash, usr, myself = this, urlLanguage = null;
- this.buildPanes();
- world.add(this);
- world.userMenu = this.userMenu;
-
// get persistent user data, if any
if (localStorage) {
usr = localStorage['-snap-user'];
@@ -245,10 +242,17 @@ IDE_Morph.prototype.openIn = function (world) {
if (usr) {
SnapCloud.username = usr.username || null;
SnapCloud.password = usr.password || null;
+ if (SnapCloud.username) {
+ this.source = 'cloud';
+ }
}
}
}
+ this.buildPanes();
+ world.add(this);
+ world.userMenu = this.userMenu;
+
// override SnapCloud's user message with Morphic
SnapCloud.message = function (string) {
var m = new MenuMorph(null, string),
@@ -284,7 +288,8 @@ IDE_Morph.prototype.openIn = function (world) {
}
throw new Error('unable to retrieve ' + url);
} catch (err) {
- return;
+ myself.showMessage('unable to retrieve project');
+ return '';
}
}
@@ -455,6 +460,7 @@ IDE_Morph.prototype.createControlBar = function () {
stopButton,
pauseButton,
startButton,
+ muteSoundsButton,
projectButton,
settingsButton,
stageSizeButton,
@@ -544,6 +550,38 @@ IDE_Morph.prototype.createControlBar = function () {
this.controlBar.add(appModeButton);
this.controlBar.appModeButton = appModeButton; // for refreshing
+ //muteSoundsButton
+ button = new ToggleButtonMorph(
+ null, //colors,
+ myself, // the IDE is the target
+ 'toggleMuteSounds',
+ [
+ new SymbolMorph('mutedSounds', 14),
+ new SymbolMorph('unmutedSounds', 14)
+ ],
+ function () { // query
+ return myself.isMuted;
+ }
+ );
+
+ button.corner = 12;
+ button.color = colors[0];
+ button.highlightColor = colors[1];
+ button.pressColor = colors[2];
+ button.labelMinExtent = new Point(36, 18);
+ button.padding = 0;
+ button.labelShadowOffset = new Point(-1, -1);
+ button.labelShadowColor = colors[1];
+ button.labelColor = this.buttonLabelColor;
+ button.contrast = this.buttonContrast;
+ button.drawNew();
+ // button.hint = 'sounds\nmuted & unmuted';
+ button.fixLayout();
+ button.refresh();
+ muteSoundsButton = button;
+ this.controlBar.add(muteSoundsButton);
+ this.controlBar.muteSoundsButton = button; // for refreshing
+
// stopButton
button = new PushButtonMorph(
this,
@@ -703,10 +741,12 @@ IDE_Morph.prototype.createControlBar = function () {
}
);
- x = myself.right() - (StageMorph.prototype.dimensions.x
- * (myself.isSmallStage ? myself.stageRatio : 1));
-
- [stageSizeButton, appModeButton].forEach(
+ x = Math.min(
+ startButton.left() - (3 * padding + 2 * stageSizeButton.width()),
+ myself.right() - StageMorph.prototype.dimensions.x *
+ (myself.isSmallStage ? myself.stageRatio : 1)
+ );
+ [stageSizeButton, appModeButton, muteSoundsButton].forEach(
function (button) {
x += padding;
button.setCenter(myself.controlBar.center());
@@ -1566,7 +1606,12 @@ IDE_Morph.prototype.droppedBinary = function (anArrayBuffer, name) {
myself = this,
suffix = name.substring(name.length - 3);
- if (suffix.toLowerCase() !== 'ypr') {return; }
+ if (suffix.toLowerCase() !== 'ypr') {
+ var zip = new JSZip(anArrayBuffer);
+ myself.droppedText(Snapin8r(zip));
+
+ return;
+ }
function loadYPR(buffer, lbl) {
var reader = new sb.Reader(),
@@ -1859,7 +1904,7 @@ IDE_Morph.prototype.newSpriteName = function (name, ignoredSprite) {
stem = (ix < 0) ? name : name.substring(0, ix),
count = 1,
newName = stem,
- all = this.sprites.asArray().filter(
+ all = this.sprites.asArray().concat(this.stage).filter(
function (each) {return each !== ignoredSprite; }
).map(
function (each) {return each.name; }
@@ -2509,8 +2554,9 @@ IDE_Morph.prototype.aboutSnap = function () {
+ 'jens@moenig.org, bh@cs.berkeley.edu\n\n'
+ 'Snap! is developed by the University of California, Berkeley\n'
- + ' with support from the National Science Foundation '
- + 'and MioSoft. \n'
+ + ' with support from the National Science Foundation, '
+ + 'MioSoft, \n'
+ + 'and the Communications Design Group at SAP Labs. \n'
+ 'The design of Snap! is influenced and inspired by Scratch,\n'
+ 'from the Lifelong Kindergarten group at the MIT Media Lab\n\n'
@@ -3326,15 +3372,20 @@ IDE_Morph.prototype.toggleAppMode = function (appMode) {
IDE_Morph.prototype.toggleStageSize = function (isSmall) {
var myself = this,
- world = this.world();
+ smallRatio = 0.5,
+ world = this.world(),
+ shiftClicked = (world.currentKey === 16);
+
+ function toggle() {
+ myself.isSmallStage = isNil(isSmall) ? !myself.isSmallStage : isSmall;
+ }
function zoomIn() {
- myself.stageRatio = 1;
myself.step = function () {
- myself.stageRatio -= (myself.stageRatio - 0.5) / 2;
+ myself.stageRatio -= (myself.stageRatio - smallRatio) / 2;
myself.setExtent(world.extent());
- if (myself.stageRatio < 0.6) {
- myself.stageRatio = 0.5;
+ if (myself.stageRatio < (smallRatio + 0.1)) {
+ myself.stageRatio = smallRatio;
myself.setExtent(world.extent());
delete myself.step;
}
@@ -3343,11 +3394,11 @@ IDE_Morph.prototype.toggleStageSize = function (isSmall) {
function zoomOut() {
myself.isSmallStage = true;
- myself.stageRatio = 0.5;
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();
@@ -3356,7 +3407,15 @@ IDE_Morph.prototype.toggleStageSize = function (isSmall) {
};
}
- this.isSmallStage = isNil(isSmall) ? !this.isSmallStage : isSmall;
+ if (shiftClicked) {
+ smallRatio = SpriteIconMorph.prototype.thumbSize.x * 3 /
+ this.stage.dimensions.x;
+ if (!this.isSmallStage || (smallRatio === this.stageRatio)) {
+ toggle();
+ }
+ } else {
+ toggle();
+ }
if (this.isAnimating) {
if (this.isSmallStage) {
zoomIn();
@@ -3364,11 +3423,32 @@ IDE_Morph.prototype.toggleStageSize = function (isSmall) {
zoomOut();
}
} else {
- if (this.isSmallStage) {this.stageRatio = 0.5; }
+ if (this.isSmallStage) {this.stageRatio = smallRatio; }
this.setExtent(world.extent());
}
};
+IDE_Morph.prototype.toggleMuteSounds = function (isMuted) {
+ this.isMuted = isNil(isMuted) ? !this.isMuted : isMuted;
+ this.controlBar.muteSoundsButton.refresh();
+
+ /* stage.activeSounds holds all active sounds
+ * a sprite's .activeSounds holds just its own
+ * so you have to use the stage to mute
+ * and the sprite to unmute, because the stage's volume
+ * overrides the sprite's one.
+ */
+
+ if (this.isMuted === false) {
+ this.stage.unmuteAllSounds();
+ this.sprites.asArray().forEach(function (sprt) {
+ sprt.unmuteAllSounds();
+ });
+ } else {
+ this.stage.muteAllSounds();
+ }
+};
+
IDE_Morph.prototype.createNewProject = function () {
var myself = this;
this.confirm(
@@ -3417,6 +3497,7 @@ IDE_Morph.prototype.setLanguage = function (lang, callback) {
if (lang === 'en') {
return this.reflectLanguage('en', callback);
}
+ myself.userLanguage = lang;
translation = document.createElement('script');
translation.id = 'language';
translation.onload = function () {
@@ -3429,6 +3510,12 @@ IDE_Morph.prototype.setLanguage = function (lang, callback) {
IDE_Morph.prototype.reflectLanguage = function (lang, callback) {
var projectData;
SnapTranslator.language = lang;
+ this.world().children.forEach(function (morph) {
+ if (morph instanceof BlockEditorMorph) {
+ morph.updateDefinition(); // save custom blocks
+ // otherwise, initBlocks() will reset the definition
+ }
+ });
if (!this.loadNewProject) {
if (Process.prototype.isCatchingErrors) {
try {
@@ -5947,7 +6034,7 @@ WardrobeMorph.prototype.removeCostumeAt = function (idx) {
WardrobeMorph.prototype.paintNew = function () {
var cos = new Costume(
newCanvas(),
- this.sprite.newCostumeName('Untitled')
+ this.sprite.newCostumeName(localize('Untitled'))
),
ide = this.parentThatIsA(IDE_Morph),
myself = this;