diff options
| -rw-r--r-- | blocks.js | 43 | ||||
| -rw-r--r-- | byob.js | 4 | ||||
| -rw-r--r-- | gui.js | 17 | ||||
| -rw-r--r-- | help/receiveInteraction.png (renamed from help/receiveClick.png) | bin | 49453 -> 49453 bytes | |||
| -rwxr-xr-x | history.txt | 17 | ||||
| -rw-r--r-- | lang-de.js | 21 | ||||
| -rw-r--r-- | locale.js | 4 | ||||
| -rw-r--r-- | objects.js | 89 | ||||
| -rw-r--r-- | store.js | 11 | ||||
| -rw-r--r-- | threads.js | 4 |
10 files changed, 171 insertions, 39 deletions
@@ -155,7 +155,7 @@ DialogBoxMorph, BlockInputFragmentMorph, PrototypeHatBlockMorph, Costume*/ // Global stuff //////////////////////////////////////////////////////// -modules.blocks = '2014-November-21'; +modules.blocks = '2015-February-28'; var SyntaxElementMorph; @@ -340,6 +340,7 @@ SyntaxElementMorph.prototype.setScale = function (num) { }; SyntaxElementMorph.prototype.setScale(1); +SyntaxElementMorph.prototype.isCachingInputs = true; // SyntaxElementMorph instance creation: @@ -356,6 +357,7 @@ SyntaxElementMorph.prototype.init = function () { SyntaxElementMorph.uber.init.call(this); this.defaults = []; + this.cachedInputs = null; }; // SyntaxElementMorph accessing: @@ -375,10 +377,12 @@ SyntaxElementMorph.prototype.parts = function () { SyntaxElementMorph.prototype.inputs = function () { // answer my arguments and nested reporters - return this.parts().filter(function (part) { - return part instanceof SyntaxElementMorph; - }); - + if (isNil(this.cachedInputs) || !this.isCachingInputs) { + this.cachedInputs = this.parts().filter(function (part) { + return part instanceof SyntaxElementMorph; + }); + } + return this.cachedInputs; }; SyntaxElementMorph.prototype.allInputs = function () { @@ -494,6 +498,7 @@ SyntaxElementMorph.prototype.replaceInput = function (oldArg, newArg) { replacement.drawNew(); this.fixLayout(); } + this.cachedInputs = null; this.endLayout(); }; @@ -529,6 +534,7 @@ SyntaxElementMorph.prototype.silentReplaceInput = function (oldArg, newArg) { replacement.drawNew(); this.fixLayout(); } + this.cachedInputs = null; }; SyntaxElementMorph.prototype.revertToDefaultInput = function (arg, noValues) { @@ -571,6 +577,7 @@ SyntaxElementMorph.prototype.revertToDefaultInput = function (arg, noValues) { } else if (deflt instanceof RingMorph) { deflt.fixBlockColor(); } + this.cachedInputs = null; }; SyntaxElementMorph.prototype.isLocked = function () { @@ -848,6 +855,20 @@ SyntaxElementMorph.prototype.labelPart = function (spec) { true // read-only ); break; + case '%interaction': + part = new InputSlotMorph( + null, // text + false, // numeric? + { + 'clicked' : ['clicked'], + 'pressed' : ['pressed'], + 'dropped' : ['dropped'], + 'mouse-entered' : ['mouse-entered'], + 'mouse-departed' : ['mouse-departed'] + }, + true // read-only + ); + break; case '%dates': part = new InputSlotMorph( null, // text @@ -1928,6 +1949,7 @@ BlockMorph.prototype.init = function () { BlockMorph.uber.init.call(this); this.color = new Color(0, 17, 173); + this.cashedInputs = null; }; BlockMorph.prototype.receiver = function () { @@ -2033,6 +2055,7 @@ BlockMorph.prototype.setSpec = function (spec) { }); this.blockSpec = spec; this.fixLayout(); + this.cachedInputs = null; }; BlockMorph.prototype.buildSpec = function () { @@ -2425,6 +2448,7 @@ BlockMorph.prototype.restoreInputs = function (oldInputs) { } i += 1; }); + this.cachedInputs = null; }; BlockMorph.prototype.showHelp = function () { @@ -3020,6 +3044,7 @@ BlockMorph.prototype.fullCopy = function () { //block.comment = null; }); + ans.cachedInputs = null; return ans; }; @@ -9172,6 +9197,10 @@ MultiArgMorph.prototype = new ArgMorph(); MultiArgMorph.prototype.constructor = MultiArgMorph; MultiArgMorph.uber = ArgMorph.prototype; +// MultiArgMorph preferences settings + +MultiArgMorph.prototype.isCachingInputs = false; + // MultiArgMorph instance creation: function MultiArgMorph( @@ -9602,6 +9631,10 @@ ArgLabelMorph.prototype = new ArgMorph(); ArgLabelMorph.prototype.constructor = ArgLabelMorph; ArgLabelMorph.uber = ArgMorph.prototype; +// ArgLabelMorph preferences settings + +ArgLabelMorph.prototype.isCachingInputs = false; + // MultiArgMorph instance creation: function ArgLabelMorph(argMorph, labelTxt) { @@ -106,7 +106,7 @@ SymbolMorph, isNil*/ // Global stuff //////////////////////////////////////////////////////// -modules.byob = '2015-January-21'; +modules.byob = '2015-February-28'; // Declarations @@ -2974,7 +2974,7 @@ InputSlotDialogMorph.prototype.editSlotOptions = function () { new DialogBoxMorph( myself, function (options) { - myself.fragment.options = options; + myself.fragment.options = options.trim(); }, myself ).promptCode( @@ -69,7 +69,7 @@ SpeechBubbleMorph*/ // Global stuff //////////////////////////////////////////////////////// -modules.gui = '2015-February-20'; +modules.gui = '2015-February-28'; // Declarations @@ -2268,6 +2268,17 @@ IDE_Morph.prototype.settingsMenu = function () { 'check to prioritize\nscript execution' ); addPreference( + 'Cache Inputs', + function () { + SyntaxElementMorph.prototype.isCachingInputs = + !SyntaxElementMorph.prototype.isCachingInputs; + }, + SyntaxElementMorph.prototype.isCachingInputs, + 'uncheck to stop caching\ninputs (for debugging the evaluator)', + 'check to cache inputs\nboosts recursion', + true + ); + addPreference( 'Rasterize SVGs', function () { MorphicPreferences.rasterizeSVGs = @@ -2377,8 +2388,8 @@ IDE_Morph.prototype.projectMenu = function () { menu.addItem( 'Save to disk', 'saveProjectToDisk', - 'store this project\nin your downloads folder\n' - + '(not supported by all browsers)' + 'store this project\nin the downloads folder\n' + + '(in supporting browsers)' ); menu.addItem('Save As...', 'saveProjectsBrowser'); menu.addLine(); diff --git a/help/receiveClick.png b/help/receiveInteraction.png Binary files differindex 6ace2e3..6ace2e3 100644 --- a/help/receiveClick.png +++ b/help/receiveInteraction.png diff --git a/history.txt b/history.txt index e125b70..1f0ec00 100755 --- a/history.txt +++ b/history.txt @@ -2441,3 +2441,20 @@ ______ * Un-hide “Save to disk” feature (currently supported by both Chrome and Firefox, but not by Safari) * Update German translation * GUI: Make “project data in URLs” a hidden dev option (prevent long urls per default) + +150223 +------ +* Blocks, Objects: Add user-interaction choices to the “When I am ...” hat block +* Update German translation +* Store: Avoid incompatibility warning for very old (pre-earmarked) projects + +150224 +------ +* Store: fixed #725 + +150228 +------ +* Blocks, Store, GUI: Cache inputs, accelerates evaluating recursive reporters and warped / turbo recursive commands by up to 40% +* Objects: slightly optimize warped / turbo execution +* Threads: fixed #715 +* BYOB: fixed #716 @@ -185,7 +185,7 @@ SnapTranslator.dict.de = { 'translator_e-mail': 'jens@moenig.org', // optional 'last_changed': - '2015-02-20', // this, too, will appear in the Translators tab + '2015-02-23', // this, too, will appear in the Translators tab // GUI // control bar: @@ -417,8 +417,18 @@ SnapTranslator.dict.de = { 'Wenn %greenflag angeklickt', 'when %keyHat key pressed': 'Wenn Taste %keyHat gedr\u00fcckt', - 'when I am clicked': - 'Wenn ich angeklickt werde', + 'when I am %interaction': + 'Wenn ich %interaction werde', + 'clicked': + 'angeklickt', + 'pressed': + 'gedr\u00fcckt', + 'dropped': + 'abgestellt', + 'mouse-entered': + 'vom Mauszeiger betreten', + 'mouse-departed': + 'vom Mauszeiger verlassen', 'when I receive %msgHat': 'Wenn ich %msgHat empfange', 'broadcast %msg': @@ -649,8 +659,9 @@ SnapTranslator.dict.de = { 'Sichern', 'Save to disk': 'Abpeichern', - 'store this project\nin your downloads folder\n(not supported by all browsers)': - 'dieses Projekt herunterladen\nund lokal speichern\n(nicht von allen Browsern unters\u00fctzt)', + 'store this project\nin the downloads folder\n(in supporting browsers)': + 'dieses Projekt herunterladen\nund lokal speichern\n' + + '(nicht von allen Browsern unters\u00fctzt)', 'Save As...': 'Sichern als...', 'Import...': @@ -42,7 +42,7 @@ /*global modules, contains*/ -modules.locale = '2015-February-20'; +modules.locale = '2015-February-23'; // Global stuff @@ -149,7 +149,7 @@ SnapTranslator.dict.de = { 'translator_e-mail': 'jens@moenig.org', 'last_changed': - '2015-02-20' + '2015-02-23' }; SnapTranslator.dict.it = { @@ -125,7 +125,7 @@ PrototypeHatBlockMorph*/ // Global stuff //////////////////////////////////////////////////////// -modules.objects = '2015-January-28'; +modules.objects = '2015-February-28'; var SpriteMorph; var StageMorph; @@ -621,11 +621,22 @@ SpriteMorph.prototype.initBlocks = function () { category: 'control', spec: 'when %keyHat key pressed' }, + + /* migrated to a newer block version: + receiveClick: { type: 'hat', category: 'control', spec: 'when I am clicked' }, + */ + + receiveInteraction: { + type: 'hat', + category: 'control', + spec: 'when I am %interaction', + defaults: ['clicked'] + }, receiveMessage: { type: 'hat', category: 'control', @@ -1245,6 +1256,10 @@ SpriteMorph.prototype.initBlockMigrations = function () { doStopBlock: { selector: 'doStopThis', inputs: [['this block']] + }, + receiveClick: { + selector: 'receiveInteraction', + inputs: [['clicked']] } }; }; @@ -1293,8 +1308,6 @@ SpriteMorph.prototype.blockAlternatives = { setSize: ['changeSize'], // control: - receiveGo: ['receiveClick'], - receiveClick: ['receiveGo'], doBroadcast: ['doBroadcastAndWait'], doBroadcastAndWait: ['doBroadcast'], doIf: ['doIfElse', 'doUntil'], @@ -1496,15 +1509,13 @@ SpriteMorph.prototype.setName = function (string) { SpriteMorph.prototype.drawNew = function () { var myself = this, - currentCenter = this.center(), + currentCenter, facing, // actual costume heading based on my rotation style isFlipped, - isLoadingCostume = this.costume && - typeof this.costume.loaded === 'function', + isLoadingCostume, cst, pic, // (flipped copy of) actual costume based on my rotation style - stageScale = this.parent instanceof StageMorph ? - this.parent.scale : 1, + stageScale, newX, corners = [], origin, @@ -1518,6 +1529,11 @@ SpriteMorph.prototype.drawNew = function () { this.wantsRedraw = true; return; } + currentCenter = this.center(); + isLoadingCostume = this.costume && + typeof this.costume.loaded === 'function'; + stageScale = this.parent instanceof StageMorph ? + this.parent.scale : 1; facing = this.rotationStyle ? this.heading : 90; if (this.rotationStyle === 2) { facing = 90; @@ -1666,7 +1682,7 @@ SpriteMorph.prototype.blockForSelector = function (selector, setDefaults) { : new ReporterBlockMorph(info.type === 'predicate'); block.color = this.blockColor[info.category]; block.category = info.category; - block.selector = selector; + block.selector = migration ? migration.selector : selector; if (contains(['reifyReporter', 'reifyPredicate'], block.selector)) { block.isStatic = true; } @@ -1920,7 +1936,7 @@ SpriteMorph.prototype.blockTemplates = function (category) { blocks.push(block('receiveGo')); blocks.push(block('receiveKey')); - blocks.push(block('receiveClick')); + blocks.push(block('receiveInteraction')); blocks.push(block('receiveMessage')); blocks.push('-'); blocks.push(block('doBroadcast')); @@ -3274,6 +3290,7 @@ SpriteMorph.prototype.prepareToBeGrabbed = function (hand) { SpriteMorph.prototype.justDropped = function () { this.restoreLayers(); this.positionTalkBubble(); + this.receiveUserInteraction('dropped'); }; // SpriteMorph drawing: @@ -3604,9 +3621,6 @@ SpriteMorph.prototype.allHatBlocksFor = function (message) { if (morph.selector === 'receiveOnClone') { return message === '__clone__init__'; } - if (morph.selector === 'receiveClick') { - return message === '__click__'; - } } return false; }); @@ -3623,13 +3637,37 @@ SpriteMorph.prototype.allHatBlocksForKey = function (key) { }); }; +SpriteMorph.prototype.allHatBlocksForInteraction = function (interaction) { + return this.scripts.children.filter(function (morph) { + if (morph.selector) { + if (morph.selector === 'receiveInteraction') { + return morph.inputs()[0].evaluate()[0] === interaction; + } + } + return false; + }); +}; + // SpriteMorph events SpriteMorph.prototype.mouseClickLeft = function () { - var stage = this.parentThatIsA(StageMorph), - hats = this.allHatBlocksFor('__click__'), - procs = []; + return this.receiveUserInteraction('clicked'); +}; + +SpriteMorph.prototype.mouseEnter = function () { + return this.receiveUserInteraction('mouse-entered'); +}; + +SpriteMorph.prototype.mouseDownLeft = function () { + return this.receiveUserInteraction('pressed'); +}; +SpriteMorph.prototype.receiveUserInteraction = function (interaction) { + var stage = this.parentThatIsA(StageMorph), + procs = [], + hats; + if (!stage) {return; } // currently dragged + hats = this.allHatBlocksForInteraction(interaction); hats.forEach(function (block) { procs.push(stage.threads.startProcess(block, stage.isThreadSafe)); }); @@ -4294,6 +4332,7 @@ SpriteMorph.prototype.mouseEnterDragging = function () { }; SpriteMorph.prototype.mouseLeave = function () { + this.receiveUserInteraction('mouse-departed'); if (!this.enableNesting) {return; } this.removeHighlight(); }; @@ -5063,7 +5102,7 @@ StageMorph.prototype.blockTemplates = function (category) { blocks.push(block('receiveGo')); blocks.push(block('receiveKey')); - blocks.push(block('receiveClick')); + blocks.push(block('receiveInteraction')); blocks.push(block('receiveMessage')); blocks.push('-'); blocks.push(block('doBroadcast')); @@ -5617,11 +5656,27 @@ StageMorph.prototype.allHatBlocksFor StageMorph.prototype.allHatBlocksForKey = SpriteMorph.prototype.allHatBlocksForKey; +StageMorph.prototype.allHatBlocksForInteraction + = SpriteMorph.prototype.allHatBlocksForInteraction; + // StageMorph events StageMorph.prototype.mouseClickLeft = SpriteMorph.prototype.mouseClickLeft; +StageMorph.prototype.mouseEnter + = SpriteMorph.prototype.mouseEnter; + +StageMorph.prototype.mouseLeave = function () { + this.receiveUserInteraction('mouse-departed'); +}; + +StageMorph.prototype.mouseDownLeft + = SpriteMorph.prototype.mouseDownLeft; + +StageMorph.prototype.receiveUserInteraction + = SpriteMorph.prototype.receiveUserInteraction; + // StageMorph custom blocks StageMorph.prototype.deleteAllBlockInstances @@ -61,7 +61,7 @@ SyntaxElementMorph, Variable*/ // Global stuff //////////////////////////////////////////////////////// -modules.store = '2015-January-21'; +modules.store = '2015-February-28'; // XML_Serializer /////////////////////////////////////////////////////// @@ -320,7 +320,7 @@ SnapSerializer.prototype.loadProjectModel = function (xmlNode, ide) { var appInfo = xmlNode.attributes.app, app = appInfo ? appInfo.split(' ')[0] : null; - if (ide && app !== this.app.split(' ')[0]) { + if (ide && app && app !== this.app.split(' ')[0]) { ide.inform( app + ' Project', 'This project has been created by a different app:\n\n' + @@ -977,7 +977,11 @@ SnapSerializer.prototype.loadBlock = function (model, isReporter) { ); } if (!receiver) { - return this.obsoleteBlock(isReporter); + if (!isGlobal) { + receiver = this.project.stage; + } else { + return this.obsoleteBlock(isReporter); + } } if (isGlobal) { info = detect(receiver.globalBlocks, function (block) { @@ -1023,6 +1027,7 @@ SnapSerializer.prototype.loadBlock = function (model, isReporter) { this.loadInput(child, inputs[i], block); } }, this); + block.cachedInputs = null; return block; }; @@ -83,7 +83,7 @@ ArgLabelMorph, localize, XML_Element, hex_sha512*/ // Global stuff //////////////////////////////////////////////////////// -modules.threads = '2015-January-12'; +modules.threads = '2015-February-28'; var ThreadManager; var Process; @@ -1926,7 +1926,7 @@ Process.prototype.reportTypeOf = function (thing) { if (thing === true || (thing === false)) { return 'Boolean'; } - if (!isNaN(parseFloat(thing))) { + if (!isNaN(+thing)) { return 'number'; } if (isString(thing)) { |
