kopia lustrzana https://github.com/backface/turtlestitch
optional upvars referencing event data for message, key and scene hat blocks
rodzic
8d2a7c8f92
commit
0ab3ee7d4c
|
@ -10,7 +10,7 @@
|
|||
* user defined custom block palettes
|
||||
* PWA, thanks, Joan and John, for pioneering this at Robolot and in Mircoblocks!
|
||||
* new "blocksZoom=n" url parameter, thanks, Bernat!
|
||||
* new "When I receive message" hat block featuring an upvar for the transmission, experimental in dev mode
|
||||
* message, key and scene hat blocks can be expanded to show an optional upvar referencing their event data
|
||||
* **Notable Changes:**
|
||||
* saved projects remember the last edited sprite
|
||||
* libraries no longer rely on the JSF primitive, project may need to re-import their libraries to run without having to enable JS extensions
|
||||
|
@ -18,6 +18,7 @@
|
|||
* display blocks with their error messages for custom blocks, thanks, Michael!
|
||||
* made scrollbars thinner by default and slightly transparent in flat design mode
|
||||
* blocked xhr requests to from Snap! to s.b.e
|
||||
* the "message" reporter and watcher in the control category has been deprecated and moved to dev mode for backwards compatibility
|
||||
* **Notable Fixes:**
|
||||
* made scrollbars in the wardrobe and jukebox more responsive
|
||||
* fixed centering of menus, thanks, Brian Broll!
|
||||
|
@ -33,6 +34,9 @@
|
|||
* German
|
||||
* Chinese, thanks, Simon!
|
||||
|
||||
### 2021-09-30
|
||||
* blocks, objects, threads, gui: optional upvars referencing event data for message, key and scene hat blocks
|
||||
|
||||
### 2021-09-29
|
||||
* objects, blocks: refactored experimental "When I receive message" hat block
|
||||
|
||||
|
|
|
@ -16,11 +16,11 @@
|
|||
<script src="src/morphic.js?version=2021-07-09"></script>
|
||||
<script src="src/symbols.js?version=2021-03-03"></script>
|
||||
<script src="src/widgets.js?version=2021-07-21"></script>
|
||||
<script src="src/blocks.js?version=2021-09-29"></script>
|
||||
<script src="src/threads.js?version=2021-09-28"></script>
|
||||
<script src="src/objects.js?version=2021-09-29"></script>
|
||||
<script src="src/blocks.js?version=2021-09-30"></script>
|
||||
<script src="src/threads.js?version=2021-09-30"></script>
|
||||
<script src="src/objects.js?version=2021-09-30"></script>
|
||||
<script src="src/scenes.js?version=2021-07-21"></script>
|
||||
<script src="src/gui.js?version=2021-09-07"></script>
|
||||
<script src="src/gui.js?version=2021-09-30"></script>
|
||||
<script src="src/paint.js?version=2021-07-05"></script>
|
||||
<script src="src/lists.js?version=2021-07-19"></script>
|
||||
<script src="src/byob.js?version=2021-08-03"></script>
|
||||
|
|
|
@ -160,7 +160,7 @@ CustomCommandBlockMorph, ToggleButtonMorph, DialMorph, SnapExtensions*/
|
|||
|
||||
// Global stuff ////////////////////////////////////////////////////////
|
||||
|
||||
modules.blocks = '2021-September-29';
|
||||
modules.blocks = '2021-September-30';
|
||||
|
||||
var SyntaxElementMorph;
|
||||
var BlockMorph;
|
||||
|
@ -983,6 +983,7 @@ SyntaxElementMorph.prototype.labelParts = {
|
|||
label: (optional)
|
||||
tags: 'widget' // doesn't count as "empty" slot implicit parameter
|
||||
min: (optional) number of minimum inputs) or zero
|
||||
max: (optional) number of maximum inputs) or zero
|
||||
defaults: (optional) number of visible slots to begin with or zero
|
||||
*/
|
||||
'%inputs': {
|
||||
|
@ -991,6 +992,13 @@ SyntaxElementMorph.prototype.labelParts = {
|
|||
label: 'with inputs',
|
||||
tags: 'widget'
|
||||
},
|
||||
'%send': {
|
||||
type: 'multi',
|
||||
slots: '%s',
|
||||
label: 'and send',
|
||||
tags: 'static',
|
||||
max: 1
|
||||
},
|
||||
'%scriptVars': {
|
||||
type: 'multi',
|
||||
slots: '%t',
|
||||
|
@ -1003,6 +1011,18 @@ SyntaxElementMorph.prototype.labelParts = {
|
|||
label: 'block variables',
|
||||
tags: 'widget'
|
||||
},
|
||||
'%message': {
|
||||
type: 'multi',
|
||||
slots: '%t',
|
||||
tags: 'widget',
|
||||
max: 1
|
||||
},
|
||||
'%keyName': {
|
||||
type: 'multi',
|
||||
slots: '%t',
|
||||
tags: 'widget',
|
||||
max: 1
|
||||
},
|
||||
'%parms': {
|
||||
type: 'multi',
|
||||
slots: '%t',
|
||||
|
@ -1654,6 +1674,7 @@ SyntaxElementMorph.prototype.labelPart = function (spec) {
|
|||
info.min || 0,
|
||||
spec
|
||||
);
|
||||
part.maxInputs = info.max;
|
||||
for (i = 0; i < info.defaults || 0; i += 1) {
|
||||
part.addInput();
|
||||
}
|
||||
|
@ -11599,6 +11620,7 @@ MultiArgMorph.prototype.init = function (
|
|||
this.slotSpec = slotSpec || '%s';
|
||||
this.labelText = localize(labelTxt || '');
|
||||
this.minInputs = min || 0;
|
||||
this.maxInputs = null;
|
||||
this.elementSpec = eSpec || null;
|
||||
this.labelColor = labelColor || null;
|
||||
this.shadowColor = shadowColor || null;
|
||||
|
@ -11748,6 +11770,8 @@ MultiArgMorph.prototype.fixArrowsLayout = function () {
|
|||
rightArrow = arrows.children[1],
|
||||
inpCount = this.inputs().length,
|
||||
dim = new Point(rightArrow.width() / 2, rightArrow.height());
|
||||
leftArrow.show();
|
||||
rightArrow.show();
|
||||
if (inpCount < (this.minInputs + 1)) { // hide left arrow
|
||||
if (label) {
|
||||
label.hide();
|
||||
|
@ -11768,6 +11792,11 @@ MultiArgMorph.prototype.fixArrowsLayout = function () {
|
|||
rightArrow.show();
|
||||
rightArrow.setPosition(leftArrow.topCenter());
|
||||
arrows.bounds.corner = rightArrow.bottomRight().copy();
|
||||
if (!isNil(this.maxInputs) && inpCount > this.maxInputs - 1) {
|
||||
// hide right arrow
|
||||
rightArrow.hide();
|
||||
arrows.setExtent(dim);
|
||||
}
|
||||
}
|
||||
arrows.rerender();
|
||||
};
|
||||
|
@ -11826,6 +11855,10 @@ MultiArgMorph.prototype.addInput = function (contents) {
|
|||
} else {
|
||||
newPart.setContents('#' + idx);
|
||||
}
|
||||
} else if (this.elementSpec === '%message') {
|
||||
newPart.setContents(localize('message'));
|
||||
} else if (this.elementSpec === '%keyName') {
|
||||
newPart.setContents(localize('key'));
|
||||
}
|
||||
newPart.parent = this;
|
||||
this.children.splice(idx, 0, newPart);
|
||||
|
|
|
@ -85,7 +85,7 @@ Animation, BoxMorph, BlockDialogMorph, RingMorph, Project, ZERO, BLACK*/
|
|||
|
||||
// Global stuff ////////////////////////////////////////////////////////
|
||||
|
||||
modules.gui = '2021-September-07';
|
||||
modules.gui = '2021-September-30';
|
||||
|
||||
// Declarations
|
||||
|
||||
|
@ -5744,7 +5744,7 @@ IDE_Morph.prototype.openProject = function (project) {
|
|||
);
|
||||
};
|
||||
|
||||
IDE_Morph.prototype.switchToScene = function (scene, refreshAlbum) {
|
||||
IDE_Morph.prototype.switchToScene = function (scene, refreshAlbum, msg) {
|
||||
var appMode = this.isAppMode;
|
||||
if (!scene || !scene.stage) {
|
||||
return;
|
||||
|
@ -5781,7 +5781,7 @@ IDE_Morph.prototype.switchToScene = function (scene, refreshAlbum) {
|
|||
}
|
||||
this.toggleAppMode(appMode);
|
||||
this.world().keyboardFocus = this.stage;
|
||||
this.stage.fireChangeOfSceneEvent();
|
||||
this.stage.fireChangeOfSceneEvent(msg);
|
||||
};
|
||||
|
||||
IDE_Morph.prototype.setURL = function (str) {
|
||||
|
|
|
@ -86,7 +86,7 @@ AlignmentMorph, Process, WorldMap, copyCanvas, useBlurredShadows*/
|
|||
|
||||
/*jshint esversion: 6*/
|
||||
|
||||
modules.objects = '2021-September-29';
|
||||
modules.objects = '2021-September-30';
|
||||
|
||||
var SpriteMorph;
|
||||
var StageMorph;
|
||||
|
@ -729,7 +729,7 @@ SpriteMorph.prototype.initBlocks = function () {
|
|||
receiveKey: {
|
||||
type: 'hat',
|
||||
category: 'control',
|
||||
spec: 'when %keyHat key pressed',
|
||||
spec: 'when %keyHat key pressed %keyName',
|
||||
defaults: [['space']]
|
||||
},
|
||||
receiveInteraction: {
|
||||
|
@ -741,14 +741,7 @@ SpriteMorph.prototype.initBlocks = function () {
|
|||
receiveMessage: {
|
||||
type: 'hat',
|
||||
category: 'control',
|
||||
spec: 'when I receive %msgHat'
|
||||
},
|
||||
receiveTransmission: { // experimental v7
|
||||
dev: true,
|
||||
type: 'hat',
|
||||
category: 'control',
|
||||
spec: 'when I receive %t',
|
||||
defaults: [['message']]
|
||||
spec: 'when I receive %msgHat %message'
|
||||
},
|
||||
receiveCondition: {
|
||||
type: 'hat',
|
||||
|
@ -913,12 +906,12 @@ SpriteMorph.prototype.initBlocks = function () {
|
|||
receiveOnScene: {
|
||||
type: 'hat',
|
||||
category: 'control',
|
||||
spec: 'when switched to this scene'
|
||||
spec: 'when switched to this scene %message'
|
||||
},
|
||||
doSwitchToScene: {
|
||||
type: 'command',
|
||||
category: 'control',
|
||||
spec: 'switch to scene %scn',
|
||||
spec: 'switch to scene %scn %send',
|
||||
defaults: [['next']]
|
||||
},
|
||||
|
||||
|
@ -2524,8 +2517,6 @@ SpriteMorph.prototype.blockTemplates = function (category = 'motion') {
|
|||
blocks.push(block('doBroadcast'));
|
||||
blocks.push(block('doBroadcastAndWait'));
|
||||
blocks.push(block('doSend'));
|
||||
blocks.push(watcherToggle('getLastMessage'));
|
||||
blocks.push(block('getLastMessage'));
|
||||
blocks.push('-');
|
||||
blocks.push(block('doWarp'));
|
||||
blocks.push('-');
|
||||
|
@ -2569,7 +2560,8 @@ SpriteMorph.prototype.blockTemplates = function (category = 'motion') {
|
|||
blocks.push('-');
|
||||
blocks.push(this.devModeText());
|
||||
blocks.push('-');
|
||||
blocks.push(block('receiveTransmission'));
|
||||
blocks.push(watcherToggle('getLastMessage'));
|
||||
blocks.push(block('getLastMessage'));
|
||||
}
|
||||
|
||||
} else if (category === 'sensing') {
|
||||
|
@ -6109,11 +6101,6 @@ SpriteMorph.prototype.allHatBlocksFor = function (message) {
|
|||
&& message !== '__clone__init__'
|
||||
&& message !== '__scene__init__');
|
||||
}
|
||||
if (sel === 'receiveTransmission') {
|
||||
return message !== '__shout__go__'
|
||||
&& message !== '__clone__init__'
|
||||
&& message !== '__scene__init__';
|
||||
}
|
||||
if (sel === 'receiveGo') {
|
||||
return message === '__shout__go__';
|
||||
}
|
||||
|
@ -8441,13 +8428,25 @@ StageMorph.prototype.fireKeyEvent = function (key) {
|
|||
}
|
||||
this.children.concat(this).forEach(morph => {
|
||||
if (isSnapObject(morph)) {
|
||||
morph.allHatBlocksForKey(evt).forEach(block =>
|
||||
morph.allHatBlocksForKey(evt).forEach(block => {
|
||||
var varName = block.inputs()[1].evaluate()[0],
|
||||
varFrame;
|
||||
if (varName) {
|
||||
varFrame = new VariableFrame();
|
||||
varFrame.addVar(varName, evt);
|
||||
}
|
||||
procs.push(this.threads.startProcess(
|
||||
block,
|
||||
morph,
|
||||
true // ignore running scripts, was: myself.isThreadSafe
|
||||
))
|
||||
);
|
||||
true, // ignore running scripts, was: myself.isThreadSafe
|
||||
null, // exportResult (bool)
|
||||
null, // callback
|
||||
null, // isClicked
|
||||
null, // rightAway
|
||||
null, // atomic
|
||||
varFrame
|
||||
));
|
||||
});
|
||||
}
|
||||
});
|
||||
return procs;
|
||||
|
@ -8464,18 +8463,30 @@ StageMorph.prototype.processKeyPress = function (event) {
|
|||
StageMorph.prototype.inspectKeyEvent
|
||||
= CursorMorph.prototype.inspectKeyEvent;
|
||||
|
||||
StageMorph.prototype.fireChangeOfSceneEvent = function () {
|
||||
StageMorph.prototype.fireChangeOfSceneEvent = function (message) {
|
||||
var procs = [];
|
||||
|
||||
this.children.concat(this).forEach(morph => {
|
||||
if (isSnapObject(morph)) {
|
||||
morph.allHatBlocksFor('__scene__init__').forEach(block =>
|
||||
morph.allHatBlocksFor('__scene__init__').forEach(block => {
|
||||
var varName = block.inputs()[0].evaluate()[0],
|
||||
varFrame;
|
||||
if (varName) {
|
||||
varFrame = new VariableFrame();
|
||||
varFrame.addVar(varName, isNil(message) ? '' : message);
|
||||
}
|
||||
procs.push(this.threads.startProcess(
|
||||
block,
|
||||
morph,
|
||||
this.isThreadSafe
|
||||
))
|
||||
);
|
||||
this.isThreadSafe,
|
||||
null, // exportResult (bool)
|
||||
null, // callback
|
||||
null, // isClicked
|
||||
null, // rightAway
|
||||
null, // atomic
|
||||
varFrame
|
||||
));
|
||||
});
|
||||
}
|
||||
});
|
||||
return procs;
|
||||
|
@ -8747,8 +8758,6 @@ StageMorph.prototype.blockTemplates = function (category = 'motion') {
|
|||
blocks.push(block('receiveCondition'));
|
||||
blocks.push('-');
|
||||
blocks.push(block('receiveMessage'));
|
||||
blocks.push(watcherToggle('getLastMessage'));
|
||||
blocks.push(block('getLastMessage'));
|
||||
blocks.push(block('doBroadcast'));
|
||||
blocks.push(block('doBroadcastAndWait'));
|
||||
blocks.push(block('doSend'));
|
||||
|
@ -8793,7 +8802,8 @@ StageMorph.prototype.blockTemplates = function (category = 'motion') {
|
|||
blocks.push('-');
|
||||
blocks.push(this.devModeText());
|
||||
blocks.push('-');
|
||||
blocks.push(block('receiveTransmission'));
|
||||
blocks.push(watcherToggle('getLastMessage'));
|
||||
blocks.push(block('getLastMessage'));
|
||||
}
|
||||
|
||||
} else if (category === 'sensing') {
|
||||
|
|
|
@ -64,7 +64,7 @@ SnapExtensions, AlignmentMorph, TextMorph, Cloud*/
|
|||
|
||||
/*jshint esversion: 6*/
|
||||
|
||||
modules.threads = '2021-September-28';
|
||||
modules.threads = '2021-September-30';
|
||||
|
||||
var ThreadManager;
|
||||
var Process;
|
||||
|
@ -3729,15 +3729,15 @@ Process.prototype.doBroadcast = function (message) {
|
|||
if (msg !== '') {
|
||||
stage.lastMessage = message; // the actual data structure
|
||||
rcvrs.forEach(morph => {
|
||||
var varFrame;
|
||||
if (isSnapObject(morph)) {
|
||||
morph.allHatBlocksFor(msg).forEach(block => {
|
||||
if (block.selector === 'receiveTransmission') {
|
||||
varFrame = new VariableFrame();
|
||||
varFrame.addVar(
|
||||
block.inputs()[0].evaluate(),
|
||||
message
|
||||
);
|
||||
var varName, varFrame;
|
||||
if (block.selector === 'receiveMessage') {
|
||||
varName = block.inputs()[1].evaluate()[0];
|
||||
if (varName) {
|
||||
varFrame = new VariableFrame();
|
||||
varFrame.addVar(varName, message);
|
||||
}
|
||||
procs.push(stage.threads.startProcess(
|
||||
block,
|
||||
morph,
|
||||
|
@ -4724,11 +4724,11 @@ Process.prototype.goToLayer = function (name) {
|
|||
|
||||
// Process scene primitives
|
||||
|
||||
Process.prototype.doSwitchToScene = function (id) {
|
||||
Process.prototype.doSwitchToScene = function (id, transmission) {
|
||||
var rcvr = this.blockReceiver(),
|
||||
idx = 0,
|
||||
message = transmission.at(1),
|
||||
ide, scenes, num, scene;
|
||||
|
||||
this.assertAlive(rcvr);
|
||||
if (this.readyToTerminate || this.topBlock.selector === 'receiveOnScene') {
|
||||
// let the user press "stop" or "esc",
|
||||
|
@ -4762,7 +4762,7 @@ Process.prototype.doSwitchToScene = function (id) {
|
|||
}
|
||||
this.stop();
|
||||
// ide.onNextStep = () => // slow down scene switching, disabled for now
|
||||
ide.switchToScene(scenes.at(idx));
|
||||
ide.switchToScene(scenes.at(idx), null, message);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -4776,8 +4776,7 @@ Process.prototype.doSwitchToScene = function (id) {
|
|||
}
|
||||
|
||||
this.stop();
|
||||
// ide.onNextStep = () => // slow down scene switching, disabled for now
|
||||
ide.switchToScene(scene);
|
||||
ide.switchToScene(scene, null, message);
|
||||
};
|
||||
|
||||
// Process color primitives
|
||||
|
|
Ładowanie…
Reference in New Issue