kopia lustrzana https://github.com/backface/turtlestitch
rearranged Snap! API into its own file
rodzic
639dbf2361
commit
8e2fafb9c6
|
@ -16,6 +16,9 @@
|
|||
* NEW Slovak translation, thanks, Peter Lukacovic
|
||||
* German
|
||||
|
||||
### 2019-12-18
|
||||
* gui, api: rearranged Snap! API into its own file
|
||||
|
||||
### 2019-12-16
|
||||
* gui, objects: added ability to add general message listeners for "any" message
|
||||
* gui: added IDE >> getMessages() to Snap! API
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<script type="text/javascript" src="src/blocks.js?version=2019-12-13"></script>
|
||||
<script type="text/javascript" src="src/threads.js?version=2019-12-15"></script>
|
||||
<script type="text/javascript" src="src/objects.js?version=2019-12-16"></script>
|
||||
<script type="text/javascript" src="src/gui.js?version=2019-12-16"></script>
|
||||
<script type="text/javascript" src="src/gui.js?version=2019-12-18"></script>
|
||||
<script type="text/javascript" src="src/paint.js?version=2019-06-27"></script>
|
||||
<script type="text/javascript" src="src/lists.js?version=2019-12-08"></script>
|
||||
<script type="text/javascript" src="src/byob.js?version=2019-07-12"></script>
|
||||
|
@ -22,6 +22,7 @@
|
|||
<script type="text/javascript" src="src/store.js?version=2019-12-09"></script>
|
||||
<script type="text/javascript" src="src/locale.js?version=2019-12-10"></script>
|
||||
<script type="text/javascript" src="src/cloud.js?version=2019-10-09"></script>
|
||||
<script type="text/javascript" src="src/api.js?version=2019-12-18"></script>
|
||||
<script type="text/javascript" src="src/sha512.js?version=2019-06-27"></script>
|
||||
<script type="text/javascript" src="src/FileSaver.min.js?version=2019-06-27"></script>
|
||||
<script type="text/javascript">
|
||||
|
|
|
@ -0,0 +1,307 @@
|
|||
/*
|
||||
|
||||
api.js
|
||||
|
||||
programmatically interact with a Snap! project
|
||||
|
||||
written by Jens Mönig
|
||||
jens@moenig.org
|
||||
|
||||
Copyright (C) 2019 by Jens Mönig
|
||||
|
||||
This file is part of Snap!.
|
||||
|
||||
Snap! is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
prerequisites:
|
||||
--------------
|
||||
needs gui.js and morphic.js
|
||||
|
||||
|
||||
documentation
|
||||
-------------
|
||||
the experimental Snap! API is a set of methods for an IDE_Morph containing
|
||||
a Snap! project. These methods are maintained to work with future versions
|
||||
of Snap! They can be used to trigger scripts, get feedback from running
|
||||
scripts, and access the project's global variables. Currently the API
|
||||
consists of the following methods:
|
||||
|
||||
Broadcast Messages (and optionally wait)
|
||||
|
||||
- IDE_Morph.prototype.broadcast()
|
||||
|
||||
Listen to Messages
|
||||
|
||||
- IDE_Morph.prototype.addMessageListenerForAll()
|
||||
- IDE_Morph.prototype.addMessageListener()
|
||||
- IDE_Morph.prototype.getMessages()
|
||||
|
||||
Access Global Variables
|
||||
|
||||
- IDE_Morph.prototype.getVarNames()
|
||||
- IDE_Morph.prototype.getVar()
|
||||
- IDE_Morph.prototype.setVar()
|
||||
|
||||
Getting hold of an ide can usually be achieved by
|
||||
evaluating:
|
||||
|
||||
var ide = world.children[0];
|
||||
|
||||
|
||||
IDE_Morph.prototype.broadcast()
|
||||
===============================
|
||||
The broadcast() method triggers all scripts whose hat block listens to
|
||||
the specified message. An optional callback can be added to be run
|
||||
after all triggered scripts have terminated.
|
||||
|
||||
syntax:
|
||||
-------
|
||||
ide.broadcast(message [, callback]);
|
||||
|
||||
parameters:
|
||||
-----------
|
||||
message
|
||||
string, the message to be sent to all listeners
|
||||
callback | optional
|
||||
function to execute after all scripts terminate, no arguments
|
||||
|
||||
return value:
|
||||
-------------
|
||||
undefined
|
||||
|
||||
|
||||
IDE_Morph.prototype.addMessageListenerForAll()
|
||||
==============================================
|
||||
The addMessageListenerForAll() method sets up a function that will be
|
||||
called whenever a message is broadcast. The function takes one argument,
|
||||
the message being broadcast, and can be used to react to any message.
|
||||
Multiple message listeners can be set up, they all the executed in the
|
||||
order in which they were added.
|
||||
|
||||
syntax:
|
||||
-------
|
||||
ide.addMessageListenerForAll(callback);
|
||||
|
||||
parameters:
|
||||
-----------
|
||||
callback
|
||||
function to execute whenever a message is sent,
|
||||
takes one argument: The message string
|
||||
|
||||
return value:
|
||||
-------------
|
||||
undefined
|
||||
|
||||
|
||||
IDE_Morph.prototype.addMessageListener()
|
||||
========================================
|
||||
The addMessageListener() method sets up a function that will be called
|
||||
whenever the specified message is broadcast. Multiple message listeners
|
||||
can be set up per message, they all the executed in the order in which
|
||||
they were added.
|
||||
|
||||
syntax:
|
||||
-------
|
||||
ide.addMessageListener(message, callback);
|
||||
|
||||
parameters:
|
||||
-----------
|
||||
message
|
||||
string, the message to which the listener will react.
|
||||
If the message is an empty string the callback will
|
||||
be executed at any broadcast, passing the message as
|
||||
argument
|
||||
callback
|
||||
function to execute whenever the specified message is sent,
|
||||
takes no argument, except when the message to listen to is
|
||||
the empty string, then it takes the message as argument
|
||||
|
||||
return value:
|
||||
-------------
|
||||
undefined
|
||||
|
||||
|
||||
IDE_Morph.prototype.getMessages()
|
||||
=================================
|
||||
The getMessage() method returns a new Array that contains all the message
|
||||
strings that occur in the project, both in hat blocks and in broadcast
|
||||
blocks.
|
||||
|
||||
syntax:
|
||||
-------
|
||||
ide.getMessages();
|
||||
|
||||
return value:
|
||||
-------------
|
||||
an Array of strings, or an empty Array
|
||||
|
||||
|
||||
IDE_Morph.prototype.getVarNames()
|
||||
=================================
|
||||
The getVarNames() method returns a new Array that contains all the global
|
||||
variable names in the project.
|
||||
|
||||
syntax:
|
||||
-------
|
||||
ide.getVarNames();
|
||||
|
||||
return value:
|
||||
-------------
|
||||
an Array of strings, or an empty Array
|
||||
|
||||
|
||||
IDE_Morph.prototype.getVar()
|
||||
=============================
|
||||
The getVar() method returns the value of the global variable indicated by
|
||||
the specified name.
|
||||
|
||||
syntax:
|
||||
-------
|
||||
ide.getVar(name);
|
||||
|
||||
return value:
|
||||
-------------
|
||||
whatever value the variable holds.
|
||||
|
||||
|
||||
IDE_Morph.prototype.setVar()
|
||||
============================
|
||||
The setVar() methods assigns a value to the a global variable specified
|
||||
by name.
|
||||
|
||||
syntax:
|
||||
=======
|
||||
ide.setVar(name, value);
|
||||
|
||||
return value:
|
||||
=============
|
||||
undefined
|
||||
|
||||
|
||||
*/
|
||||
|
||||
/*global modules, IDE_Morph, isString, Map*/
|
||||
|
||||
// Global stuff ////////////////////////////////////////////////////////
|
||||
|
||||
modules.api = '2019-December-18';
|
||||
|
||||
// IDE_Morph external communication API - experimental
|
||||
/*
|
||||
programmatically trigger scripts from outside of Snap!
|
||||
add message listeners to Snap! broadcasts and access
|
||||
global variables
|
||||
*/
|
||||
|
||||
IDE_Morph.prototype.broadcast = function(message, callback) {
|
||||
// same as using the broadcast block - launch all scripts
|
||||
// in the current project reacting to the specified message,
|
||||
// if a callback is supplied wait for all processes to terminate
|
||||
// then call the callback, same as using the "broadcast and wait" block
|
||||
|
||||
var rcvrs = this.sprites.contents.concat(this.stage),
|
||||
myself = this,
|
||||
procs = [];
|
||||
|
||||
function wait() {
|
||||
if (procs.some(function (any) {return any.isRunning(); })) {
|
||||
return;
|
||||
}
|
||||
if (callback instanceof Function) {
|
||||
myself.onNextStep = function () {
|
||||
callback();
|
||||
callback = null;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (!isString(message)) {
|
||||
throw new Error('message must be a String');
|
||||
}
|
||||
this.stage.lastMessage = message;
|
||||
rcvrs.forEach(function (sprite) {
|
||||
sprite.allHatBlocksFor(message).forEach(function (block) {
|
||||
procs.push(myself.stage.threads.startProcess(
|
||||
block,
|
||||
sprite,
|
||||
myself.stage.isThreadSafe,
|
||||
false,
|
||||
callback instanceof Function ? wait : null
|
||||
));
|
||||
});
|
||||
});
|
||||
(this.stage.messageCallbacks[''] || []).forEach(function (callback) {
|
||||
callback(message);
|
||||
});
|
||||
(this.stage.messageCallbacks[message] || []).forEach(function (callback) {
|
||||
callback();
|
||||
});
|
||||
};
|
||||
|
||||
IDE_Morph.prototype.addMessageListenerForAll = function (callback) {
|
||||
// associate a monadic callback with all broadcasts.
|
||||
// whenever a message is broadcast the callback is called
|
||||
// with the current message as argument
|
||||
this.addMessageListener('', callback);
|
||||
};
|
||||
|
||||
IDE_Morph.prototype.addMessageListener = function (message, callback) {
|
||||
// associate a callback function with a broadcast message,
|
||||
// whenever the message is broadcast, the callback is executed,
|
||||
// you can add multiple callbacks to a message, they will be
|
||||
// executed in the order you added them.
|
||||
// Note: ssociating a callback with an empty string attaches the
|
||||
// callback to "any" message, taking the actual message as argument
|
||||
var funcs;
|
||||
if (!isString(message)) {
|
||||
throw new Error('message must be a String');
|
||||
}
|
||||
funcs = this.stage.messageCallbacks[message];
|
||||
if (funcs instanceof Array) {
|
||||
funcs.push(callback);
|
||||
} else {
|
||||
this.stage.messageCallbacks[message] = [callback];
|
||||
}
|
||||
};
|
||||
|
||||
IDE_Morph.prototype.getMessages = function () {
|
||||
// return an array of all broadcast messages in the current project
|
||||
var allNames = [],
|
||||
dict = new Map();
|
||||
this.sprites.contents.concat(this.stage).forEach(function (sprite) {
|
||||
allNames = allNames.concat(sprite.allMessageNames());
|
||||
});
|
||||
allNames.forEach(function (name) {
|
||||
dict.set(name);
|
||||
});
|
||||
return Array.from(dict.keys());
|
||||
};
|
||||
|
||||
IDE_Morph.prototype.getVarNames = function () {
|
||||
// return an array of all global variable names
|
||||
return this.stage.globalVariables().names();
|
||||
};
|
||||
|
||||
IDE_Morph.prototype.getVar = function (name) {
|
||||
// return the value of the global variable indicated by name
|
||||
// raise an error if no global variable of that name exists
|
||||
return this.stage.globalVariables().getVar(name);
|
||||
};
|
||||
|
||||
IDE_Morph.prototype.setVar = function (name, value) {
|
||||
// set the value of the global variable indicated by name to the given value
|
||||
// raise an error if no global variable of that name exists
|
||||
this.stage.globalVariables().setVar(name, value);
|
||||
};
|
133
src/gui.js
133
src/gui.js
|
@ -61,25 +61,24 @@
|
|||
|
||||
*/
|
||||
|
||||
/*global modules, Morph, SpriteMorph, SyntaxElementMorph, Color, Cloud, Map,
|
||||
ListWatcherMorph, TextMorph, newCanvas, useBlurredShadows, VariableFrame,
|
||||
/*global modules, Morph, SpriteMorph, SyntaxElementMorph, Color, Cloud, Audio,
|
||||
ListWatcherMorph, TextMorph, newCanvas, useBlurredShadows, VariableFrame, Sound,
|
||||
StringMorph, Point, MenuMorph, morphicVersion, DialogBoxMorph, normalizeCanvas,
|
||||
ToggleButtonMorph, contains, ScrollFrameMorph, StageMorph, PushButtonMorph, sb,
|
||||
InputFieldMorph, FrameMorph, Process, nop, SnapSerializer, ListMorph, detect,
|
||||
AlignmentMorph, TabMorph, Costume, MorphicPreferences, Sound, BlockMorph,
|
||||
ToggleMorph, InputSlotDialogMorph, ScriptsMorph, isNil, SymbolMorph, fontHeight,
|
||||
BlockExportDialogMorph, BlockImportDialogMorph, SnapTranslator, localize, List,
|
||||
ArgMorph, Uint8Array, HandleMorph, SVG_Costume, TableDialogMorph, isString,
|
||||
CommentMorph, CommandBlockMorph, BooleanSlotMorph, RingReporterSlotMorph,
|
||||
BlockLabelPlaceHolderMorph, Audio, SpeechBubbleMorph, ScriptFocusMorph,
|
||||
XML_Element, WatcherMorph, BlockRemovalDialogMorph, saveAs, TableMorph,
|
||||
isSnapObject, isRetinaEnabled, disableRetinaSupport, enableRetinaSupport,
|
||||
isRetinaSupported, SliderMorph, Animation, BoxMorph, MediaRecorder,
|
||||
BlockEditorMorph, BlockDialogMorph*/
|
||||
AlignmentMorph, TabMorph, Costume, MorphicPreferences,BlockMorph, ToggleMorph,
|
||||
InputSlotDialogMorph, ScriptsMorph, isNil, SymbolMorph, fontHeight, localize,
|
||||
BlockExportDialogMorph, BlockImportDialogMorph, SnapTranslator, List, ArgMorph,
|
||||
Uint8Array, HandleMorph, SVG_Costume, TableDialogMorph, CommentMorph, saveAs,
|
||||
CommandBlockMorph, BooleanSlotMorph, RingReporterSlotMorph, ScriptFocusMorph,
|
||||
BlockLabelPlaceHolderMorph, SpeechBubbleMorph, XML_Element, WatcherMorph,
|
||||
BlockRemovalDialogMorph,TableMorph, isSnapObject, isRetinaEnabled, SliderMorph,
|
||||
disableRetinaSupport, enableRetinaSupport, isRetinaSupported, MediaRecorder,
|
||||
Animation, BoxMorph, BlockEditorMorph, BlockDialogMorph*/
|
||||
|
||||
// Global stuff ////////////////////////////////////////////////////////
|
||||
|
||||
modules.gui = '2019-December-16';
|
||||
modules.gui = '2019-December-18';
|
||||
|
||||
// Declarations
|
||||
|
||||
|
@ -6058,114 +6057,6 @@ IDE_Morph.prototype.isIE = function () {
|
|||
return ua.indexOf("MSIE ") > -1 || ua.indexOf("Trident/") > -1;
|
||||
};
|
||||
|
||||
// IDE_Morph external communication API - experimental
|
||||
/*
|
||||
programmatically trigger scripts from outside of Snap!
|
||||
add message listeners to Snap! broadcasts and access
|
||||
global variables
|
||||
*/
|
||||
|
||||
IDE_Morph.prototype.broadcast = function(message, callback) {
|
||||
// same as using the broadcast block - launch all scripts
|
||||
// in the current project reacting to the specified message,
|
||||
// if a callback is supplied wait for all processes to terminate
|
||||
// then call the callback, same as using the "broadcast and wait" block
|
||||
|
||||
var rcvrs = this.sprites.contents.concat(this.stage),
|
||||
myself = this,
|
||||
procs = [];
|
||||
|
||||
function wait() {
|
||||
if (procs.some(function (any) {return any.isRunning(); })) {
|
||||
return;
|
||||
}
|
||||
if (callback instanceof Function) {
|
||||
myself.onNextStep = function () {
|
||||
callback();
|
||||
callback = null;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (!isString(message)) {
|
||||
throw new Error('message must be a String');
|
||||
}
|
||||
this.stage.lastMessage = message;
|
||||
rcvrs.forEach(function (sprite) {
|
||||
sprite.allHatBlocksFor(message).forEach(function (block) {
|
||||
procs.push(myself.stage.threads.startProcess(
|
||||
block,
|
||||
sprite,
|
||||
myself.stage.isThreadSafe,
|
||||
false,
|
||||
callback instanceof Function ? wait : null
|
||||
));
|
||||
});
|
||||
});
|
||||
(this.stage.messageCallbacks[''] || []).forEach(function (callback) {
|
||||
callback(message);
|
||||
});
|
||||
(this.stage.messageCallbacks[message] || []).forEach(function (callback) {
|
||||
callback();
|
||||
});
|
||||
};
|
||||
|
||||
IDE_Morph.prototype.addMessageListenerForAll = function (callback) {
|
||||
// associate a monadic callback with all broadcasts.
|
||||
// whenever a message is broadcast the callback is called
|
||||
// with the current message as argument
|
||||
this.addMessageListener('', callback);
|
||||
};
|
||||
|
||||
IDE_Morph.prototype.addMessageListener = function (message, callback) {
|
||||
// associate a callback function with a broadcast message,
|
||||
// whenever the message is broadcast, the callback is executed,
|
||||
// you can add multiple callbacks to a message, they will be
|
||||
// executed in the order you added them.
|
||||
// Note: ssociating a callback with an empty string attaches the
|
||||
// callback to "any" message, taking the actual message as argument
|
||||
var funcs;
|
||||
if (!isString(message)) {
|
||||
throw new Error('message must be a String');
|
||||
}
|
||||
funcs = this.stage.messageCallbacks[message];
|
||||
if (funcs instanceof Array) {
|
||||
funcs.push(callback);
|
||||
} else {
|
||||
this.stage.messageCallbacks[message] = [callback];
|
||||
}
|
||||
};
|
||||
|
||||
IDE_Morph.prototype.getMessages = function () {
|
||||
// return an array of all broadcast messages in the current project
|
||||
var allNames = [],
|
||||
dict = new Map();
|
||||
this.sprites.contents.concat(this.stage).forEach(function (sprite) {
|
||||
allNames = allNames.concat(sprite.allMessageNames());
|
||||
});
|
||||
allNames.forEach(function (name) {
|
||||
dict.set(name);
|
||||
});
|
||||
return Array.from(dict.keys());
|
||||
};
|
||||
|
||||
IDE_Morph.prototype.getVarNames = function () {
|
||||
// return an array of all global variable names
|
||||
return this.stage.globalVariables().names();
|
||||
};
|
||||
|
||||
IDE_Morph.prototype.getVar = function (name) {
|
||||
// return the value of the global variable indicated by name
|
||||
// raise an error if no global variable of that name exists
|
||||
return this.stage.globalVariables().getVar(name);
|
||||
};
|
||||
|
||||
IDE_Morph.prototype.setVar = function (name, value) {
|
||||
// set the value of the global variable indicated by name to the given value
|
||||
// raise an error if no global variable of that name exists
|
||||
this.stage.globalVariables().setVar(name, value);
|
||||
};
|
||||
|
||||
// ProjectDialogMorph ////////////////////////////////////////////////////
|
||||
|
||||
// ProjectDialogMorph inherits from DialogBoxMorph:
|
||||
|
|
Ładowanie…
Reference in New Issue