diff options
Diffstat (limited to 'gui.js')
| -rw-r--r-- | gui.js | 246 |
1 files changed, 193 insertions, 53 deletions
@@ -9,7 +9,7 @@ written by Jens Mönig jens@moenig.org - Copyright (C) 2014 by Jens Mönig + Copyright (C) 2015 by Jens Mönig This file is part of Snap!. @@ -69,7 +69,7 @@ SpeechBubbleMorph*/ // Global stuff //////////////////////////////////////////////////////// -modules.gui = '2014-November-20'; +modules.gui = '2015-June-25'; // Declarations @@ -82,6 +82,11 @@ var WardrobeMorph; var SoundIconMorph; var JukeboxMorph; +// Get the full url without "snap.html" +var baseUrl = document.URL.split('/'); +baseUrl.pop(baseUrl.length - 1); +baseUrl = baseUrl.join('/') + '/'; + // IDE_Morph /////////////////////////////////////////////////////////// // I am SNAP's top-level frame, the Editor window @@ -119,7 +124,7 @@ IDE_Morph.prototype.setDefaultDesign = function () { ]; IDE_Morph.prototype.rotationStyleColors = IDE_Morph.prototype.tabColors; IDE_Morph.prototype.appModeColor = new Color(); - IDE_Morph.prototype.scriptsPaneTexture = 'scriptsPaneTexture.gif'; + IDE_Morph.prototype.scriptsPaneTexture = this.scriptsTexture(); IDE_Morph.prototype.padding = 5; SpriteIconMorph.prototype.labelColor @@ -172,6 +177,22 @@ IDE_Morph.prototype.setFlatDesign = function () { = IDE_Morph.prototype.buttonLabelColor; }; +IDE_Morph.prototype.scriptsTexture = function () { + var pic = newCanvas(new Point(100, 100)), // bigger scales faster + ctx = pic.getContext('2d'), + i; + for (i = 0; i < 100; i += 4) { + ctx.fillStyle = this.frameColor.toString(); + ctx.fillRect(i, 0, 1, 100); + ctx.fillStyle = this.groupColor.lighter(6).toString(); + ctx.fillRect(i + 1, 0, 1, 100); + ctx.fillRect(i + 3, 0, 1, 100); + ctx.fillStyle = this.groupColor.toString(); + ctx.fillRect(i + 2, 0, 1, 100); + } + return pic; +}; + IDE_Morph.prototype.setDefaultDesign(); // IDE_Morph instance creation: @@ -186,11 +207,12 @@ IDE_Morph.prototype.init = function (isAutoFill) { // restore saved user preferences this.userLanguage = null; // user language preference for startup + this.projectsInURLs = false; this.applySavedSettings(); // additional properties: this.cloudMsg = null; - this.source = SnapCloud.username ? 'cloud' : 'local'; + this.source = 'local'; this.serializer = new SnapSerializer(); this.globalVariables = new VariableFrame(); @@ -233,10 +255,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 +263,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 +309,8 @@ IDE_Morph.prototype.openIn = function (world) { } throw new Error('unable to retrieve ' + url); } catch (err) { - return; + myself.showMessage('unable to retrieve project'); + return ''; } } @@ -297,7 +323,6 @@ IDE_Morph.prototype.openIn = function (world) { this.inform('Snap!', motd); } */ - function interpretUrlAnchors() { var dict; if (location.hash.substr(0, 6) === '#open:') { @@ -350,6 +375,7 @@ IDE_Morph.prototype.openIn = function (world) { function () { msg = myself.showMessage('Opening project...'); }, + function () {nop(); }, // yield (bug in Chrome) function () { if (projectData.indexOf('<snapdata') === 0) { myself.rawOpenCloudDataString(projectData); @@ -364,8 +390,61 @@ IDE_Morph.prototype.openIn = function (world) { myself.shield.destroy(); myself.shield = null; msg.destroy(); - myself.toggleAppMode(true); - myself.runScripts(); + + if (dict.editMode) { + myself.toggleAppMode(false); + } else { + myself.toggleAppMode(true); + } + + if (!dict.noRun) { + myself.runScripts(); + } + + if (dict.hideControls) { + myself.controlBar.hide(); + window.onbeforeunload = function () {nop(); }; + } + } + ]); + }, + this.cloudError() + ); + } else if (location.hash.substr(0, 7) === '#cloud:') { + this.shield = new Morph(); + this.shield.alpha = 0; + this.shield.setExtent(this.parent.extent()); + this.parent.add(this.shield); + myself.showMessage('Fetching project\nfrom the cloud...'); + + // make sure to lowercase the username + dict = SnapCloud.parseDict(location.hash.substr(7)); + dict.Username = dict.Username.toLowerCase(); + + SnapCloud.getPublicProject( + SnapCloud.encodeDict(dict), + function (projectData) { + var msg; + myself.nextSteps([ + function () { + msg = myself.showMessage('Opening project...'); + }, + function () {nop(); }, // yield (bug in Chrome) + function () { + if (projectData.indexOf('<snapdata') === 0) { + myself.rawOpenCloudDataString(projectData); + } else if ( + projectData.indexOf('<project') === 0 + ) { + myself.rawOpenProjectString(projectData); + } + myself.hasChangedMedia = true; + }, + function () { + myself.shield.destroy(); + myself.shield = null; + msg.destroy(); + myself.toggleAppMode(false); } ]); }, @@ -1149,7 +1228,7 @@ IDE_Morph.prototype.createSpriteEditor = function () { if (this.currentTab === 'scripts') { scripts.isDraggable = false; scripts.color = this.groupColor; - scripts.texture = this.scriptsPaneTexture; + scripts.cachedTexture = this.scriptsPaneTexture; this.spriteEditor = new ScrollFrameMorph( scripts, @@ -1720,6 +1799,7 @@ IDE_Morph.prototype.applySavedSettings = function () { language = this.getSetting('language'), click = this.getSetting('click'), longform = this.getSetting('longform'), + longurls = this.getSetting('longurls'), plainprototype = this.getSetting('plainprototype'); // design @@ -1753,6 +1833,13 @@ IDE_Morph.prototype.applySavedSettings = function () { InputSlotDialogMorph.prototype.isLaunchingExpanded = true; } + // project data in URLs + if (longurls) { + this.projectsInURLs = true; + } else { + this.projectsInURLs = false; + } + // plain prototype labels if (plainprototype) { BlockLabelPlaceHolderMorph.prototype.plainLabel = true; @@ -2043,6 +2130,7 @@ IDE_Morph.prototype.cloudMenu = function () { 'Opening project...' ); }, + function () {nop(); }, // yield (Chrome) function () { myself.rawOpenCloudDataString( projectData @@ -2198,6 +2286,17 @@ IDE_Morph.prototype.settingsMenu = function () { 'check to prioritize\nscript execution' ); addPreference( + 'Cache Inputs', + function () { + BlockMorph.prototype.isCachingInputs = + !BlockMorph.prototype.isCachingInputs; + }, + BlockMorph.prototype.isCachingInputs, + 'uncheck to stop caching\ninputs (for debugging the evaluator)', + 'check to cache inputs\nboosts recursion', + true + ); + addPreference( 'Rasterize SVGs', function () { MorphicPreferences.rasterizeSVGs = @@ -2222,6 +2321,21 @@ IDE_Morph.prototype.settingsMenu = function () { false ); addPreference( + 'Project URLs', + function () { + myself.projectsInURLs = !myself.projectsInURLs; + if (myself.projectsInURLs) { + myself.saveSetting('longurls', true); + } else { + myself.removeSetting('longurls'); + } + }, + myself.projectsInURLs, + 'uncheck to disable\nproject data in URLs', + 'check to enable\nproject data in URLs', + true + ); + addPreference( 'Sprite Nesting', function () { SpriteMorph.prototype.enableNesting = @@ -2293,7 +2407,8 @@ IDE_Morph.prototype.projectMenu = function () { menu.addItem( 'Save to disk', 'saveProjectToDisk', - 'experimental - store this project\nin your downloads folder', + 'store this project\nin the downloads folder\n' + + '(in supporting browsers)', new Color(100, 0, 0) ); } @@ -2382,13 +2497,10 @@ IDE_Morph.prototype.projectMenu = function () { function () { // read a list of libraries from an external file, var libMenu = new MenuMorph(this, 'Import library'), - libUrl = 'http://snap.berkeley.edu/snapsource/libraries/' + - 'LIBRARIES'; + libUrl = baseUrl + 'libraries/' + 'LIBRARIES'; function loadLib(name) { - var url = 'http://snap.berkeley.edu/snapsource/libraries/' - + name - + '.xml'; + var url = baseUrl + 'libraries/' + name + '.xml'; myself.droppedText(myself.getURL(url), name); } @@ -2505,8 +2617,8 @@ IDE_Morph.prototype.aboutSnap = function () { module, btn1, btn2, btn3, btn4, licenseBtn, translatorsBtn, world = this.world(); - aboutTxt = 'Snap! 4.0\nBuild Your Own Blocks\n\n--- beta ---\n\n' - + 'Copyright \u24B8 2014 Jens M\u00F6nig and ' + aboutTxt = 'Snap! 4.0.1\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' @@ -2539,7 +2651,7 @@ IDE_Morph.prototype.aboutSnap = function () { creditsTxt = localize('Contributors') + '\n\nNathan Dinsmore: Saving/Loading, Snap-Logo Design, ' - + 'countless bugfixes' + + '\ncountless bugfixes and optimizations' + '\nKartik Chandra: Paint Editor' + '\nMichael Ball: Time/Date UI, many bugfixes' + '\n"Ava" Yuan Yuan: Graphic Effects' @@ -2768,7 +2880,7 @@ IDE_Morph.prototype.rawSaveProject = function (name) { try { localStorage['-snap-project-' + name] = str = this.serializer.serialize(this.stage); - location.hash = '#open:' + str; + this.setURL('#open:' + str); this.showMessage('Saved!', 1); } catch (err) { this.showMessage('Save failed: ' + err); @@ -2776,7 +2888,7 @@ IDE_Morph.prototype.rawSaveProject = function (name) { } else { localStorage['-snap-project-' + name] = str = this.serializer.serialize(this.stage); - location.hash = '#open:' + str; + this.setURL('#open:' + str); this.showMessage('Saved!', 1); } } @@ -2817,7 +2929,7 @@ IDE_Morph.prototype.exportProject = function (name, plain) { str = encodeURIComponent( this.serializer.serialize(this.stage) ); - location.hash = '#open:' + str; + this.setURL('#open:' + str); window.open('data:text/' + (plain ? 'plain,' + str : 'xml,' + str)); menu.destroy(); @@ -2830,7 +2942,7 @@ IDE_Morph.prototype.exportProject = function (name, plain) { str = encodeURIComponent( this.serializer.serialize(this.stage) ); - location.hash = '#open:' + str; + this.setURL('#open:' + str); window.open('data:text/' + (plain ? 'plain,' + str : 'xml,' + str)); menu.destroy(); @@ -2855,7 +2967,9 @@ IDE_Morph.prototype.exportGlobalBlocks = function () { }; IDE_Morph.prototype.exportSprite = function (sprite) { - var str = this.serializer.serialize(sprite.allParts()); + var str = encodeURIComponent( + this.serializer.serialize(sprite.allParts()) + ); window.open('data:text/xml,<sprites app="' + this.serializer.app + '" version="' @@ -2922,6 +3036,7 @@ IDE_Morph.prototype.openProjectString = function (str) { function () { msg = myself.showMessage('Opening project...'); }, + function () {nop(); }, // yield (bug in Chrome) function () { myself.rawOpenProjectString(str); }, @@ -2940,12 +3055,18 @@ IDE_Morph.prototype.rawOpenProjectString = function (str) { StageMorph.prototype.enableCodeMapping = false; if (Process.prototype.isCatchingErrors) { try { - this.serializer.openProject(this.serializer.load(str), this); + this.serializer.openProject( + this.serializer.load(str, this), + this + ); } catch (err) { this.showMessage('Load failed: ' + err); } } else { - this.serializer.openProject(this.serializer.load(str), this); + this.serializer.openProject( + this.serializer.load(str, this), + this + ); } this.stopFastTracking(); }; @@ -2957,6 +3078,7 @@ IDE_Morph.prototype.openCloudDataString = function (str) { function () { msg = myself.showMessage('Opening project...'); }, + function () {nop(); }, // yield (bug in Chrome) function () { myself.rawOpenCloudDataString(str); }, @@ -2977,7 +3099,10 @@ IDE_Morph.prototype.rawOpenCloudDataString = function (str) { model = this.serializer.parse(str); this.serializer.loadMediaModel(model.childNamed('media')); this.serializer.openProject( - this.serializer.loadProjectModel(model.childNamed('project')), + this.serializer.loadProjectModel( + model.childNamed('project'), + this + ), this ); } catch (err) { @@ -2987,7 +3112,10 @@ IDE_Morph.prototype.rawOpenCloudDataString = function (str) { model = this.serializer.parse(str); this.serializer.loadMediaModel(model.childNamed('media')); this.serializer.openProject( - this.serializer.loadProjectModel(model.childNamed('project')), + this.serializer.loadProjectModel( + model.childNamed('project'), + this + ), this ); } @@ -3001,6 +3129,7 @@ IDE_Morph.prototype.openBlocksString = function (str, name, silently) { function () { msg = myself.showMessage('Opening blocks...'); }, + function () {nop(); }, // yield (bug in Chrome) function () { myself.rawOpenBlocksString(str, name, silently); }, @@ -3047,6 +3176,7 @@ IDE_Morph.prototype.openSpritesString = function (str) { function () { msg = myself.showMessage('Opening sprite...'); }, + function () {nop(); }, // yield (bug in Chrome) function () { myself.rawOpenSpritesString(str); }, @@ -3088,7 +3218,13 @@ IDE_Morph.prototype.openProject = function (name) { this.setProjectName(name); str = localStorage['-snap-project-' + name]; this.openProjectString(str); - location.hash = '#open:' + str; + this.setURL('#open:' + str); + } +}; + +IDE_Morph.prototype.setURL = function (str) { + if (this.projectsInURLs) { + location.hash = str; } }; @@ -3323,6 +3459,15 @@ IDE_Morph.prototype.toggleAppMode = function (appMode) { }).forEach(function (s) { s.adjustScrollBars(); }); + // prevent rotation and draggability controls from + // showing for the stage + if (this.currentSprite === this.stage) { + this.spriteBar.children.forEach(function (child) { + if (child instanceof PushButtonMorph) { + child.hide(); + } + }); + } } this.setExtent(this.world().extent()); // resume trackChanges }; @@ -3498,7 +3643,8 @@ IDE_Morph.prototype.userSetBlocksScale = function () { sample = new FrameMorph(); sample.acceptsDrops = false; - sample.texture = this.scriptsPaneTexture; + sample.color = IDE_Morph.prototype.groupColor; + sample.cachedTexture = this.scriptsPaneTexture; sample.setExtent(new Point(250, 180)); scrpt.setPosition(sample.position().add(10)); sample.add(scrpt); @@ -3971,6 +4117,9 @@ IDE_Morph.prototype.cloudResponse = function () { IDE_Morph.prototype.cloudError = function () { var myself = this; + // try finding an eplanation what's going on + // has some issues, commented out for now + /* function getURL(url) { try { var request = new XMLHttpRequest(); @@ -3984,13 +4133,15 @@ IDE_Morph.prototype.cloudError = function () { return null; } } + */ return function (responseText, url) { // first, try to find out an explanation for the error // and notify the user about it, // if none is found, show an error dialog box var response = responseText, - explanation = getURL('http://snap.berkeley.edu/cloudmsg.txt'); + // explanation = getURL('http://snap.berkeley.edu/cloudmsg.txt'), + explanation = null; if (myself.shield) { myself.shield.destroy(); myself.shield = null; @@ -4041,14 +4192,7 @@ IDE_Morph.prototype.setCloudURL = function () { null, { 'Snap!Cloud' : - 'https://snapcloud.miosoft.com/miocon/app/' + - 'login?_app=SnapCloud', - 'local network lab' : - '192.168.2.107:8087/miocon/app/login?_app=SnapCloud', - 'local network office' : - '192.168.186.146:8087/miocon/app/login?_app=SnapCloud', - 'localhost dev' : - 'localhost/miocon/app/login?_app=SnapCloud' + 'https://snap.apps.miosoft.com/SnapCloud' } ); }; @@ -4075,8 +4219,7 @@ IDE_Morph.prototype.getURLsbeOrRelative = function (url) { var request = new XMLHttpRequest(), myself = this; try { - request.open('GET', 'http://snap.berkeley.edu/snapsource/' + - url, false); + request.open('GET', baseUrl + url, false); request.send(); if (request.status === 200) { return request.responseText; @@ -4517,8 +4660,7 @@ ProjectDialogMorph.prototype.setSource = function (source) { myself.nameField.setContents(item.name || ''); } src = myself.ide.getURL( - 'http://snap.berkeley.edu/snapsource/Examples/' + - item.name + '.xml' + baseUrl + 'Examples/' + item.name + '.xml' ); xml = myself.ide.serializer.parse(src); @@ -4572,8 +4714,9 @@ ProjectDialogMorph.prototype.getLocalProjectList = function () { ProjectDialogMorph.prototype.getExamplesProjectList = function () { var dir, projects = []; + //alert(baseUrl); - dir = this.ide.getURL('http://snap.berkeley.edu/snapsource/Examples/'); + dir = this.ide.getURL(baseUrl + 'Examples/'); dir.split('\n').forEach( function (line) { var startIdx = line.search(new RegExp('href=".*xml"')), @@ -4592,8 +4735,8 @@ ProjectDialogMorph.prototype.getExamplesProjectList = function () { } } ); - projects.sort(function (x, y) { - return x.name < y.name ? -1 : 1; + projects = projects.sort(function (x, y) { + return x.name.toLowerCase() < y.name.toLowerCase() ? -1 : 1; }); return projects; }; @@ -4692,10 +4835,7 @@ ProjectDialogMorph.prototype.openProject = function () { if (this.source === 'cloud') { this.openCloudProject(proj); } else if (this.source === 'examples') { - src = this.ide.getURL( - 'http://snap.berkeley.edu/snapsource/Examples/' + - proj.name + '.xml' - ); + src = this.ide.getURL(baseUrl + 'Examples/' + proj.name + '.xml'); this.ide.openProjectString(src); this.destroy(); } else { // 'local' |
