kopia lustrzana https://github.com/backface/turtlestitch
commit
de69bf77e5
124
HISTORY.md
124
HISTORY.md
|
@ -1,5 +1,99 @@
|
|||
# Snap! (BYOB) History
|
||||
|
||||
## in development for v7:
|
||||
* **New Features:**
|
||||
* Scenes
|
||||
* unified blocks palette option, thanks, Michael!
|
||||
* **Notable Changes:**
|
||||
* saved projects remember the last edited srpite
|
||||
* **Notable Fixes:**
|
||||
* made scrollbars in the wardrobe and jukebox more responsive
|
||||
|
||||
### 2021-07-02
|
||||
* gui, object, store, etc.: unified blocks palette option, thanks, Michael!
|
||||
|
||||
### 2021-05-21
|
||||
* gui, scenes, store: proxied thumbnail, name and notes in project, restored in XML
|
||||
* gui: distinguished project name from scene names, removed hidden "export as plain text" option
|
||||
* gui: sceneified project notes
|
||||
* gui: adjusted project thumbnail in "save" dialog
|
||||
* gui: some cleanups
|
||||
* gui, scenes: sceneified unsaved changes management
|
||||
* blocks: fixed search-blocks for scenesMenu
|
||||
|
||||
### 2021-05-20
|
||||
* gui: marked projectName to be refactored and sceneified
|
||||
|
||||
### 2021-05-19
|
||||
* gui: disabled scene icon context menu for project scene
|
||||
* gui: disabled dragging the project scene icon
|
||||
* gui: made sure the project scene stays in place
|
||||
* gui: added exporting single scenes
|
||||
* scenes, store: removed redundant properties "notes" and "thumbnail" from project
|
||||
* store: removed "thumbnail" property from scene xml
|
||||
|
||||
### 2021-05-18
|
||||
* gui: fixed exporting media only for a single scene
|
||||
* gui: fixed cloud file format components
|
||||
* gui: "projectized" cloud file format for a single scene
|
||||
* gui: fixed cloud file format for multi-scene projects
|
||||
* gui: ensured unique scene names
|
||||
|
||||
### 2021-05-11
|
||||
* gui: add multi-scene projects
|
||||
* gui: adjusted scene album rendering
|
||||
* gui: tweaked scene album rendering
|
||||
|
||||
### 2021-05-10
|
||||
* gui: project menu entries for "new scene" and "add scene"
|
||||
|
||||
### 2021-04-28
|
||||
* gui: only show scene album if the project has more than a single scene
|
||||
|
||||
### 2021-04-23
|
||||
* store: serialize sprite-order from scenes
|
||||
* gui: sceneified refreshIDE()
|
||||
* gui: sceneified toggling dynamic input labels and switching languages
|
||||
* gui: sceneified "zoom blocks"
|
||||
* store: moved sprite-selection attribute from stage to scenes tag
|
||||
* scenes, store, gui: remember last edited scene in a project
|
||||
|
||||
### 2021-04-22
|
||||
* store, gui: first pass at deserializing multi-scene projects
|
||||
* gui, scenes: migrated "new project" feature
|
||||
* gui: replaced openScene() with openProject()
|
||||
|
||||
### 2021-04-21
|
||||
* store, gui: refactored project loading structure
|
||||
|
||||
### 2021-04-20
|
||||
* scenes, store, gui: multi-scene project serialization format, first pass
|
||||
|
||||
### 2021-04-16
|
||||
* scenes, store, gui: remember last edited sprite in a scene / project
|
||||
* scenes: removed Project class
|
||||
* scenes, store, gui: export multi-scene projects
|
||||
|
||||
### 2021-04-14
|
||||
* scenes: new Project class
|
||||
* store: sceneified projects
|
||||
* gui: switched to scene-based project serialization
|
||||
|
||||
### 2021-04-12
|
||||
* blocks, objects, threads, gui: new "switch to scene _" command primitive
|
||||
* morphic, gui: support bulk-file-drop for importing scenes
|
||||
* gui: tweaked scene album colors
|
||||
|
||||
### 2021-04-08
|
||||
* gui: scroll selected scene icon into view
|
||||
|
||||
### 2021-04-01
|
||||
* gui: made scrollbars in the wardrobe and jukebox more responsive
|
||||
|
||||
### 2021-04-01
|
||||
* gui: made scene icons selectable
|
||||
* gui: made scene icons observe the scene's stage versions
|
||||
|
||||
## in development:
|
||||
|
||||
* **New Features:**
|
||||
|
@ -187,6 +281,23 @@
|
|||
* fixed DEAL in the APL library, thanks, Brian!
|
||||
* objects: fixed a resizing edge case bug for the stage prompter (ASK command)
|
||||
|
||||
### 2021-03-31
|
||||
* gui: tweaked scene icon settings
|
||||
* gui: moved stage icon to the top of the corral
|
||||
|
||||
### 2021-03-30
|
||||
* gui: added documentation
|
||||
* gui: added SceneIconMorph and SceneAlbumMorph prototypes
|
||||
* gui: turned scenes into an observable list
|
||||
* gui: added scene icon thumbnails
|
||||
|
||||
### 2021-03-25
|
||||
* gui, scenes: sceneified trash
|
||||
* gui: first "live" multi-scene experiment
|
||||
|
||||
### 2021-03-19
|
||||
* gui, store, scenes: capture global settings in scenes
|
||||
|
||||
## 6.7.3
|
||||
* **Notable Changes:**
|
||||
* hyperized "key _ pressed?" predicate
|
||||
|
@ -201,7 +312,11 @@
|
|||
* threads: hyperized "key _ pressed?" predicate
|
||||
* prepared patch
|
||||
|
||||
### 2021-03-18
|
||||
* gui, scenes, objects: more scene-refactorings
|
||||
|
||||
### 2021-03-17
|
||||
* objects, gui, paint, sketch, store: de-globalized stage dimensions
|
||||
* new dev version
|
||||
* threads fixed repeat for non-numbers, thanks Stefan!
|
||||
* updated list-utilities library, thanks, Brian!
|
||||
|
@ -215,6 +330,15 @@
|
|||
* Catalan, thanks, Joan!
|
||||
|
||||
### 2021-03-15
|
||||
* gui: marked methods for scene refactorings
|
||||
|
||||
### 2021-03-12
|
||||
* scenes, gui, store: added scenes class
|
||||
|
||||
### 2021-03-11
|
||||
* gui, store: refactor loading a project into the IDE
|
||||
|
||||
### 2021-03-09
|
||||
* new dev version
|
||||
* Catalan translation update, thanks, Joan!
|
||||
* lists, apl: fixed "transpose", thanks, Brian!
|
||||
|
|
15
snap.html
15
snap.html
|
@ -3,25 +3,26 @@
|
|||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Snap! 6.10.0 - dev - Build Your Own Blocks</title>
|
||||
<title>Snap! 7 - dev - Build Your Own Blocks</title>
|
||||
<link rel="icon" href="src/favicon.ico">
|
||||
<script src="src/morphic.js?version=2021-02-10"></script>
|
||||
<script src="src/morphic.js?version=2021-04-12"></script>
|
||||
<script src="src/symbols.js?version=2021-03-03"></script>
|
||||
<script src="src/widgets.js?version=2021-01-05"></script>
|
||||
<script src="src/blocks.js?version=2021-06-18"></script>
|
||||
<script src="src/blocks.js?version=2021-07-02"></script>
|
||||
<script src="src/threads.js?version=2021-06-24"></script>
|
||||
<script src="src/objects.js?version=2021-06-14"></script>
|
||||
<script src="src/gui.js?version=2021-06-23"></script>
|
||||
<script src="src/objects.js?version=2021-07-02"></script>
|
||||
<script src="src/scenes.js?version=2021-07-02"></script>
|
||||
<script src="src/gui.js?version=2021-07-02"></script>
|
||||
<script src="src/paint.js?version=2020-05-17"></script>
|
||||
<script src="src/lists.js?version=2021-03-15"></script>
|
||||
<script src="src/byob.js?version=2021-06-24"></script>
|
||||
<script src="src/tables.js?version=2021-03-05"></script>
|
||||
<script src="src/sketch.js?version=2020-07-13"></script>
|
||||
<script src="src/sketch.js?version=2021-03-17"></script>
|
||||
<script src="src/video.js?version=2019-06-27"></script>
|
||||
<script src="src/maps.js?version=2021-06-15"></script>
|
||||
<script src="src/extensions.js?version=2021-07-02"></script>
|
||||
<script src="src/xml.js?version=2020-04-27"></script>
|
||||
<script src="src/store.js?version=2021-06-24"></script>
|
||||
<script src="src/store.js?version=2021-07-02"></script>
|
||||
<script src="src/locale.js?version=2021-06-11"></script>
|
||||
<script src="src/cloud.js?version=2021-02-04"></script>
|
||||
<script src="src/api.js?version=2021-01-25"></script>
|
||||
|
|
|
@ -158,7 +158,7 @@ CustomCommandBlockMorph, ToggleButtonMorph, DialMorph, SnapExtensions*/
|
|||
|
||||
// Global stuff ////////////////////////////////////////////////////////
|
||||
|
||||
modules.blocks = '2021-June-18';
|
||||
modules.blocks = '2021-July-02';
|
||||
|
||||
var SyntaxElementMorph;
|
||||
var BlockMorph;
|
||||
|
@ -753,6 +753,11 @@ SyntaxElementMorph.prototype.labelParts = {
|
|||
'parameters' : ['parameters']
|
||||
}
|
||||
},
|
||||
'%scn': {
|
||||
type: 'input',
|
||||
tags: 'read-only',
|
||||
menu: 'scenesMenu'
|
||||
},
|
||||
|
||||
// video
|
||||
|
||||
|
@ -926,7 +931,7 @@ SyntaxElementMorph.prototype.labelParts = {
|
|||
type: 'ring slot'
|
||||
tags: 'static',
|
||||
kind: 'command', 'reporter', 'predicate'
|
||||
|
||||
|
||||
*/
|
||||
'%rc': {
|
||||
type: 'ring slot',
|
||||
|
@ -2052,7 +2057,7 @@ SyntaxElementMorph.prototype.fixLayout = function () {
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
this.fixHighlight();
|
||||
};
|
||||
|
||||
|
@ -2460,6 +2465,7 @@ BlockSymbolMorph.prototype.getShadowRenderColor = function () {
|
|||
%r - round reporter slot
|
||||
%p - hexagonal predicate slot
|
||||
%vid - chameleon colored rectangular drop-down for video modes
|
||||
%scn - chameleon colored rectangular drop-down for scene names
|
||||
|
||||
rings:
|
||||
|
||||
|
@ -4246,7 +4252,7 @@ BlockMorph.prototype.render = function (ctx) {
|
|||
this.outlinePath(ctx, 0);
|
||||
ctx.closePath();
|
||||
ctx.fill();
|
||||
|
||||
|
||||
// add 3D-Effect:
|
||||
this.drawEdges(ctx);
|
||||
}
|
||||
|
@ -5882,11 +5888,11 @@ function ReporterBlockMorph(isPredicate) {
|
|||
ReporterBlockMorph.prototype.init = function (isPredicate) {
|
||||
ReporterBlockMorph.uber.init.call(this);
|
||||
this.isPredicate = isPredicate || false;
|
||||
|
||||
|
||||
this.bounds.setExtent(new Point(50, 22).multiplyBy(this.scale));
|
||||
this.fixLayout();
|
||||
this.rerender();
|
||||
|
||||
|
||||
this.cachedSlotSpec = null; // don't serialize
|
||||
this.isLocalVarTemplate = null; // don't serialize
|
||||
};
|
||||
|
@ -6577,7 +6583,7 @@ RingMorph.prototype.render = function (ctx) {
|
|||
// ctx.closePath();
|
||||
ctx.clip('evenodd');
|
||||
ctx.fillRect(0, 0, this.width(), this.height());
|
||||
|
||||
|
||||
// add 3D-Effect:
|
||||
this.drawEdges(ctx);
|
||||
}
|
||||
|
@ -9759,7 +9765,7 @@ InputSlotMorph.prototype.audioMenu = function (searching) {
|
|||
'spectrum' : ['spectrum'],
|
||||
'resolution' : ['resolution']
|
||||
};
|
||||
if (searching) {return {}; }
|
||||
if (searching) {return dict; }
|
||||
|
||||
if (this.world().currentKey === 16) { // shift
|
||||
dict['~'] = null;
|
||||
|
@ -9769,6 +9775,28 @@ InputSlotMorph.prototype.audioMenu = function (searching) {
|
|||
return dict;
|
||||
};
|
||||
|
||||
InputSlotMorph.prototype.scenesMenu = function (searching) {
|
||||
var dict = {},
|
||||
scenes;
|
||||
if (!searching) {
|
||||
scenes = this.parentThatIsA(IDE_Morph).scenes;
|
||||
if (scenes.length() > 1) {
|
||||
scenes.itemsArray().forEach(scn => {
|
||||
if (scn.name) {
|
||||
dict[scn.name] = scn.name;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
dict['~'] = null;
|
||||
dict.next = ['next'];
|
||||
dict.previous = ['previous'];
|
||||
dict['1 '] = 1; // trailing space needed to prevent undesired sorting
|
||||
dict.last = ['last'];
|
||||
dict.random = ['random'];
|
||||
return dict;
|
||||
};
|
||||
|
||||
InputSlotMorph.prototype.setChoices = function (dict, readonly) {
|
||||
// externally specify choices and read-only status,
|
||||
// used for custom blocks
|
||||
|
@ -11002,7 +11030,8 @@ BooleanSlotMorph.prototype.drawKnob = function (ctx, progress) {
|
|||
var w = this.width(),
|
||||
r = this.height() / 2,
|
||||
shift = this.edge / 2,
|
||||
slideStep = (this.width() - this.height()) / 4 * Math.max(0, (progress || 0)),
|
||||
slideStep = (this.width() - this.height()) / 4 *
|
||||
Math.max(0, (progress || 0)),
|
||||
gradient,
|
||||
x,
|
||||
y = r,
|
||||
|
@ -14272,7 +14301,7 @@ ScriptFocusMorph.prototype.reactToKeyEvent = function (key) {
|
|||
|
||||
cmd = new CommandBlockMorph();
|
||||
cmd.setSpec('command %cmdRing');
|
||||
|
||||
|
||||
rings = new CommandBlockMorph();
|
||||
rings.setSpec('reporter %repRing predicate %predRing');
|
||||
|
||||
|
|
1196
src/gui.js
1196
src/gui.js
Plik diff jest za duży
Load Diff
114
src/morphic.js
114
src/morphic.js
|
@ -678,6 +678,15 @@
|
|||
|
||||
droppedBinary(anArrayBuffer, name)
|
||||
|
||||
In case multiple files are dropped simulateneously the events
|
||||
|
||||
beginBulkDrop()
|
||||
endBulkDrop()
|
||||
|
||||
are dispatched to to Morphs interested in bracketing the bulk operation,
|
||||
and the endBulkDrop() event is only signalled after the contents last file
|
||||
has been asynchronously made available.
|
||||
|
||||
|
||||
(e) keyboard events
|
||||
-------------------
|
||||
|
@ -11583,6 +11592,9 @@ HandMorph.prototype.processMouseScroll = function (event) {
|
|||
droppedSVG
|
||||
droppedAudio
|
||||
droppedText
|
||||
|
||||
beginBulkDrop
|
||||
endBulkDrop
|
||||
*/
|
||||
|
||||
HandMorph.prototype.processDrop = function (event) {
|
||||
|
@ -11596,11 +11608,20 @@ HandMorph.prototype.processDrop = function (event) {
|
|||
droppedAudio(audio, name)
|
||||
droppedText(text, name, type)
|
||||
|
||||
events to interested Morphs at the mouse pointer
|
||||
events to interested Morphs at the mouse pointer.
|
||||
|
||||
In case multiple files are dropped simulateneously also displatch
|
||||
the events
|
||||
|
||||
beginBulkDrop()
|
||||
endBulkDrop()
|
||||
|
||||
to Morphs interested in bracketing the bulk operation
|
||||
*/
|
||||
var files = event instanceof FileList ? event
|
||||
: event.target.files || event.dataTransfer.files,
|
||||
file,
|
||||
fileCount,
|
||||
url = event.dataTransfer ?
|
||||
event.dataTransfer.getData('URL') : null,
|
||||
txt = event.dataTransfer ?
|
||||
|
@ -11614,11 +11635,15 @@ HandMorph.prototype.processDrop = function (event) {
|
|||
|
||||
function readSVG(aFile) {
|
||||
var pic = new Image(),
|
||||
frd = new FileReader();
|
||||
while (!target.droppedSVG) {
|
||||
target = target.parent;
|
||||
frd = new FileReader(),
|
||||
trg = target;
|
||||
while (!trg.droppedSVG) {
|
||||
trg = trg.parent;
|
||||
}
|
||||
pic.onload = () => target.droppedSVG(pic, aFile.name);
|
||||
pic.onload = () => {
|
||||
trg.droppedSVG(pic, aFile.name);
|
||||
bulkDrop();
|
||||
};
|
||||
frd = new FileReader();
|
||||
frd.onloadend = (e) => pic.src = e.target.result;
|
||||
frd.readAsDataURL(aFile);
|
||||
|
@ -11626,14 +11651,16 @@ HandMorph.prototype.processDrop = function (event) {
|
|||
|
||||
function readImage(aFile) {
|
||||
var pic = new Image(),
|
||||
frd = new FileReader();
|
||||
while (!target.droppedImage) {
|
||||
target = target.parent;
|
||||
frd = new FileReader(),
|
||||
trg = target;
|
||||
while (!trg.droppedImage) {
|
||||
trg = trg.parent;
|
||||
}
|
||||
pic.onload = () => {
|
||||
canvas = newCanvas(new Point(pic.width, pic.height), true);
|
||||
canvas.getContext('2d').drawImage(pic, 0, 0);
|
||||
target.droppedImage(canvas, aFile.name);
|
||||
trg.droppedImage(canvas, aFile.name);
|
||||
bulkDrop();
|
||||
};
|
||||
frd = new FileReader();
|
||||
frd.onloadend = (e) => pic.src = e.target.result;
|
||||
|
@ -11642,39 +11669,64 @@ HandMorph.prototype.processDrop = function (event) {
|
|||
|
||||
function readAudio(aFile) {
|
||||
var snd = new Audio(),
|
||||
frd = new FileReader();
|
||||
while (!target.droppedAudio) {
|
||||
target = target.parent;
|
||||
frd = new FileReader(),
|
||||
trg = target;
|
||||
while (!trg.droppedAudio) {
|
||||
trg = trg.parent;
|
||||
}
|
||||
frd.onloadend = (e) => {
|
||||
snd.src = e.target.result;
|
||||
target.droppedAudio(snd, aFile.name);
|
||||
trg.droppedAudio(snd, aFile.name);
|
||||
bulkDrop();
|
||||
};
|
||||
frd.readAsDataURL(aFile);
|
||||
}
|
||||
|
||||
function readText(aFile) {
|
||||
var frd = new FileReader();
|
||||
while (!target.droppedText) {
|
||||
target = target.parent;
|
||||
var frd = new FileReader(),
|
||||
trg = target;
|
||||
while (!trg.droppedText) {
|
||||
trg = trg.parent;
|
||||
}
|
||||
frd.onloadend = (e) => {
|
||||
target.droppedText(e.target.result, aFile.name, aFile.type);
|
||||
trg.droppedText(e.target.result, aFile.name, aFile.type);
|
||||
bulkDrop();
|
||||
};
|
||||
frd.readAsText(aFile);
|
||||
}
|
||||
|
||||
function readBinary(aFile) {
|
||||
var frd = new FileReader();
|
||||
while (!target.droppedBinary) {
|
||||
target = target.parent;
|
||||
var frd = new FileReader(),
|
||||
trg = target;
|
||||
while (!trg.droppedBinary) {
|
||||
trg = trg.parent;
|
||||
}
|
||||
frd.onloadend = (e) => {
|
||||
target.droppedBinary(e.target.result, aFile.name);
|
||||
trg.droppedBinary(e.target.result, aFile.name);
|
||||
bulkDrop();
|
||||
};
|
||||
frd.readAsArrayBuffer(aFile);
|
||||
}
|
||||
|
||||
function beginBulkDrop() {
|
||||
var trg = target;
|
||||
while (!trg.beginBulkDrop) {
|
||||
trg = trg.parent;
|
||||
}
|
||||
trg.beginBulkDrop();
|
||||
}
|
||||
|
||||
function bulkDrop() {
|
||||
var trg = target;
|
||||
fileCount -= 1;
|
||||
if (files.length > 1 && fileCount === 0) {
|
||||
while (!trg.endBulkDrop) {
|
||||
trg = trg.parent;
|
||||
}
|
||||
trg.endBulkDrop();
|
||||
}
|
||||
}
|
||||
|
||||
function readURL(url, callback) {
|
||||
var request = new XMLHttpRequest();
|
||||
request.open('GET', url);
|
||||
|
@ -11708,6 +11760,10 @@ HandMorph.prototype.processDrop = function (event) {
|
|||
}
|
||||
|
||||
if (files.length > 0) {
|
||||
fileCount = files.length;
|
||||
if (fileCount > 1) {
|
||||
beginBulkDrop();
|
||||
}
|
||||
for (i = 0; i < files.length; i += 1) {
|
||||
file = files[i];
|
||||
suffix = file.name.slice(
|
||||
|
@ -12250,13 +12306,17 @@ WorldMorph.prototype.wantsDropOf = function () {
|
|||
return this.acceptsDrops;
|
||||
};
|
||||
|
||||
WorldMorph.prototype.droppedImage = function () {
|
||||
return null;
|
||||
};
|
||||
WorldMorph.prototype.droppedImage = nop;
|
||||
|
||||
WorldMorph.prototype.droppedSVG = function () {
|
||||
return null;
|
||||
};
|
||||
WorldMorph.prototype.droppedSVG = nop;
|
||||
|
||||
WorldMorph.prototype.droppedAudio = nop;
|
||||
|
||||
WorldMorph.prototype.droppedText;
|
||||
|
||||
WorldMorph.prototype.beginBulkDrop = nop;
|
||||
|
||||
WorldMorph.prototype.endBulkDrop = nop;
|
||||
|
||||
// WorldMorph text field tabbing:
|
||||
|
||||
|
|
716
src/objects.js
716
src/objects.js
Plik diff jest za duży
Load Diff
25
src/paint.js
25
src/paint.js
|
@ -71,18 +71,19 @@
|
|||
|
||||
2020 Apr 14 - Morphic2 migration (Jens)
|
||||
2020 May 17 - Pipette alpha fix (Joan)
|
||||
2020 July 13 - modified scale buttons (Jadga)
|
||||
2020 Jul 13 - modified scale buttons (Jadga)
|
||||
|
||||
2021 Mar 17 - moved stage dimension handling to scenes (Jens)
|
||||
*/
|
||||
|
||||
/*global Point, Rectangle, DialogBoxMorph, AlignmentMorph, PushButtonMorph,
|
||||
Color, SymbolMorph, newCanvas, Morph, StringMorph, Costume, SpriteMorph, nop,
|
||||
localize, InputFieldMorph, SliderMorph, ToggleMorph, ToggleButtonMorph,
|
||||
BoxMorph, modules, radians, MorphicPreferences, getDocumentPositionOf,
|
||||
StageMorph, isNil, SVG_Costume*/
|
||||
/*global Point, Rectangle, DialogBoxMorph, AlignmentMorph, PushButtonMorph, nop,
|
||||
Color, SymbolMorph, newCanvas, Morph, StringMorph, Costume, SpriteMorph, isNil,
|
||||
localize, InputFieldMorph, SliderMorph, ToggleMorph, ToggleButtonMorph, modules,
|
||||
BoxMorph, radians, MorphicPreferences, getDocumentPositionOf, SVG_Costume*/
|
||||
|
||||
// Global stuff ////////////////////////////////////////////////////////
|
||||
|
||||
modules.paint = '2020-July-13';
|
||||
modules.paint = '2021-March-17';
|
||||
|
||||
// Declarations
|
||||
|
||||
|
@ -106,6 +107,7 @@ function PaintEditorMorph() {
|
|||
|
||||
PaintEditorMorph.prototype.init = function () {
|
||||
// additional properties:
|
||||
this.ide = null;
|
||||
this.paper = null; // paint canvas
|
||||
this.oncancel = null;
|
||||
|
||||
|
@ -116,15 +118,16 @@ PaintEditorMorph.prototype.init = function () {
|
|||
this.labelString = "Paint Editor";
|
||||
this.createLabel();
|
||||
|
||||
// build contents:
|
||||
this.buildContents();
|
||||
// building the contents happens when I am opened with an IDE
|
||||
// so my extent can be adjusted accordingly (jens)
|
||||
// this.buildContents();
|
||||
};
|
||||
|
||||
PaintEditorMorph.prototype.buildContents = function () {
|
||||
var myself = this;
|
||||
|
||||
this.paper = new PaintCanvasMorph(function () {return myself.shift; });
|
||||
this.paper.setExtent(StageMorph.prototype.dimensions);
|
||||
this.paper.setExtent(this.ide.stage.dimensions);
|
||||
|
||||
this.addBody(new AlignmentMorph('row', this.padding));
|
||||
this.controls = new AlignmentMorph('column', this.padding / 2);
|
||||
|
@ -293,6 +296,8 @@ PaintEditorMorph.prototype.openIn = function (
|
|||
this.callback = callback || nop;
|
||||
this.ide = anIDE;
|
||||
|
||||
this.buildContents();
|
||||
|
||||
this.processKeyUp = function () {
|
||||
myself.shift = false;
|
||||
myself.propertiesControls.constrain.refresh();
|
||||
|
|
|
@ -0,0 +1,211 @@
|
|||
/*
|
||||
|
||||
scenes.js
|
||||
|
||||
multi-scene support for Snap!
|
||||
|
||||
written by Jens Mönig
|
||||
jens@moenig.org
|
||||
|
||||
Copyright (C) 2021 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 morphic.js and objects.js
|
||||
|
||||
toc
|
||||
---
|
||||
the following list shows the order in which all constructors are
|
||||
defined. Use this list to locate code in this document:
|
||||
|
||||
Project
|
||||
Scene
|
||||
|
||||
credits
|
||||
-------
|
||||
scenes have been inspired by Ted Kaehlers's personal demos of HyperCard
|
||||
and many discussions with Ted about the design and practice of HyperCard,
|
||||
and by personal discussions with Wolfgang Slany about his design of
|
||||
scenes in Catrobat/PocketCode, which I love and admire.
|
||||
|
||||
*/
|
||||
|
||||
// Global stuff ////////////////////////////////////////////////////////
|
||||
|
||||
/*global modules, VariableFrame, StageMorph, SpriteMorph, Process, List,
|
||||
normalizeCanvas, SnapSerializer*/
|
||||
|
||||
modules.scenes = '2021-July-02';
|
||||
|
||||
|
||||
// Projecct /////////////////////////////////////////////////////////
|
||||
|
||||
// I am a container for a set of one or more Snap! scenes,
|
||||
// the IDE operates on an instance of me
|
||||
|
||||
// Project instance creation:
|
||||
|
||||
function Project(scenes, current) {
|
||||
var projectScene;
|
||||
|
||||
this.scenes = scenes || new List();
|
||||
this.currentScene = current;
|
||||
|
||||
// proxied for display
|
||||
this.name = null;
|
||||
this.notes = null;
|
||||
this.thumbnail = null;
|
||||
|
||||
projectScene = this.scenes.at(1);
|
||||
if (projectScene) {
|
||||
this.name = projectScene.name;
|
||||
this.notes = projectScene.notes;
|
||||
this.thumbnail = normalizeCanvas(
|
||||
projectScene.stage.thumbnail(SnapSerializer.prototype.thumbnailSize)
|
||||
);
|
||||
}
|
||||
|
||||
// for deserializing - do not persist
|
||||
this.sceneIdx = null;
|
||||
|
||||
// for undeleting scenes - do not persist
|
||||
this.trash = [];
|
||||
}
|
||||
|
||||
Project.prototype.initialize = function () {
|
||||
// initialize after deserializing
|
||||
// only to be called by store
|
||||
this.currentScene = this.scenes.at(+this.sceneIdx || 1);
|
||||
return this;
|
||||
};
|
||||
|
||||
Project.prototype.addDefaultScene = function () {
|
||||
var scene = new Scene();
|
||||
scene.addDefaultSprite();
|
||||
this.scenes.add(scene);
|
||||
};
|
||||
|
||||
// Scene /////////////////////////////////////////////////////////
|
||||
|
||||
// I am a container for a Snap! stage, scene-global variables
|
||||
// and its associated settings.
|
||||
// I can be used as a slide in a presentation, a chapter in a narrative,
|
||||
// a level in a game, etc.
|
||||
|
||||
// Scene instance creation:
|
||||
|
||||
function Scene(aStageMorph) {
|
||||
this.name = '';
|
||||
this.notes = '';
|
||||
this.globalVariables = aStageMorph ?
|
||||
aStageMorph.globalVariables() : new VariableFrame();
|
||||
this.stage = aStageMorph || new StageMorph(this.globalVariables);
|
||||
this.hasUnsavedEdits = false;
|
||||
this.unifiedPalette = false;
|
||||
|
||||
// cached IDE state
|
||||
this.sprites = new List();
|
||||
this.currentSprite = null;
|
||||
|
||||
// global settings (shared)
|
||||
this.hiddenPrimitives = {};
|
||||
this.codeMappings = {};
|
||||
this.codeHeaders = {};
|
||||
|
||||
// global settings (copied)
|
||||
this.enableCodeMapping = false;
|
||||
this.enableInheritance = true;
|
||||
this.enableSublistIDs = false;
|
||||
this.enablePenLogging = false;
|
||||
this.useFlatLineEnds = false;
|
||||
this.enableLiveCoding = false;
|
||||
this.enableHyperOps = true;
|
||||
|
||||
// for deserializing - do not persist
|
||||
this.spritesDict = {};
|
||||
this.targetStage = null;
|
||||
this.spriteIdx = null;
|
||||
|
||||
// for undeleting sprites - do not persist
|
||||
this.trash = [];
|
||||
}
|
||||
|
||||
Scene.prototype.initialize = function () {
|
||||
// initialize after deserializing
|
||||
// only to be called by store
|
||||
var objs = this.stage.children.filter(
|
||||
child => child instanceof SpriteMorph
|
||||
);
|
||||
objs.sort((x, y) => x.idx - y.idx);
|
||||
this.sprites = new List(objs);
|
||||
if (this.spriteIdx === null && this.sprites.length() > 0) {
|
||||
this.currentSprite = this.sprites.at(1);
|
||||
} else if (this.spriteIdx === 0) {
|
||||
this.currentSprite = this.stage;
|
||||
} else {
|
||||
this.currentSprite = this.sprites.at(this.spriteIdx) ||
|
||||
this.stage;
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
Scene.prototype.addDefaultSprite = function () {
|
||||
var sprite = new SpriteMorph(this.globalVariables);
|
||||
sprite.setPosition(
|
||||
this.stage.center().subtract(
|
||||
sprite.extent().divideBy(2)
|
||||
)
|
||||
);
|
||||
this.stage.add(sprite);
|
||||
this.sprites.add(sprite);
|
||||
this.currentSprite = sprite;
|
||||
return sprite;
|
||||
};
|
||||
|
||||
Scene.prototype.captureGlobalSettings = function () {
|
||||
this.hiddenPrimitives = StageMorph.prototype.hiddenPrimitives;
|
||||
this.unifiedPalette = StageMorph.prototype.unifiedPalette;
|
||||
this.codeMappings = StageMorph.prototype.codeMappings;
|
||||
this.codeHeaders = StageMorph.prototype.codeHeaders;
|
||||
this.enableCodeMapping = StageMorph.prototype.enableCodeMapping;
|
||||
this.enableInheritance = StageMorph.prototype.enableInheritance;
|
||||
this.enableSublistIDs = StageMorph.prototype.enableSublistIDs;
|
||||
this.enablePenLogging = StageMorph.prototype.enablePenLogging;
|
||||
this.useFlatLineEnds = SpriteMorph.prototype.useFlatLineEnds;
|
||||
this.enableLiveCoding = Process.prototype.enableLiveCoding;
|
||||
this.enableHyperOps = Process.prototype.enableHyperOps;
|
||||
};
|
||||
|
||||
Scene.prototype.applyGlobalSettings = function () {
|
||||
StageMorph.prototype.hiddenPrimitives = this.hiddenPrimitives;
|
||||
StageMorph.prototype.unifiedPalette = this.unifiedPalette;
|
||||
StageMorph.prototype.codeMappings = this.codeMappings;
|
||||
StageMorph.prototype.codeHeaders = this.codeHeaders;
|
||||
StageMorph.prototype.enableCodeMapping = this.enableCodeMapping;
|
||||
StageMorph.prototype.enableInheritance = this.enableInheritance;
|
||||
StageMorph.prototype.enableSublistIDs = this.enableSublistIDs;
|
||||
StageMorph.prototype.enablePenLogging = this.enablePenLogging;
|
||||
SpriteMorph.prototype.useFlatLineEnds = this.useFlatLineEnds;
|
||||
Process.prototype.enableLiveCoding = this.enableLiveCoding;
|
||||
Process.prototype.enableHyperOps = this.enableHyperOps;
|
||||
};
|
||||
|
||||
Scene.prototype.updateTrash = function () {
|
||||
this.trash = this.trash.filter(sprite => sprite.isCorpse);
|
||||
};
|
|
@ -54,14 +54,16 @@
|
|||
- select primary color with right-click (in addition to shift-click)
|
||||
2020, April 15 (Jens):
|
||||
- migrated to new Morphic2 architecture
|
||||
2021, March 17 (Jens):
|
||||
- moved stage dimension handling to scenes
|
||||
*/
|
||||
|
||||
/*global Point, Object, Rectangle, AlignmentMorph, Morph, XML_Element, nop,
|
||||
PaintColorPickerMorph, Color, SliderMorph, InputFieldMorph, ToggleMorph,
|
||||
TextMorph, Image, newCanvas, PaintEditorMorph, StageMorph, Costume, isNil,
|
||||
localize, PaintCanvasMorph, StringMorph, detect, modules*/
|
||||
/*global Point, Object, Rectangle, AlignmentMorph, Morph, XML_Element, localize,
|
||||
PaintColorPickerMorph, Color, SliderMorph, InputFieldMorph, ToggleMorph, isNil,
|
||||
TextMorph, Image, newCanvas, PaintEditorMorph, Costume, nop, PaintCanvasMorph,
|
||||
StringMorph, detect, modules*/
|
||||
|
||||
modules.sketch = '2020-July-13';
|
||||
modules.sketch = '2021-March-17';
|
||||
|
||||
// Declarations
|
||||
|
||||
|
@ -999,7 +1001,7 @@ VectorPaintEditorMorph.prototype.buildEdits = function () {
|
|||
};
|
||||
|
||||
VectorPaintEditorMorph.prototype.convertToBitmap = function () {
|
||||
var canvas = newCanvas(StageMorph.prototype.dimensions),
|
||||
var canvas = newCanvas(this.ide.stage.dimensions),
|
||||
myself = this;
|
||||
|
||||
this.object = new Costume();
|
||||
|
@ -1053,7 +1055,14 @@ VectorPaintEditorMorph.prototype.openIn = function (
|
|||
var myself = this,
|
||||
isEmpty = isNil(shapes) || shapes.length === 0;
|
||||
|
||||
VectorPaintEditorMorph.uber.openIn.call(this, world, null, oldrc, callback, anIDE);
|
||||
VectorPaintEditorMorph.uber.openIn.call(
|
||||
this,
|
||||
world,
|
||||
null,
|
||||
oldrc,
|
||||
callback,
|
||||
anIDE
|
||||
);
|
||||
this.ide = anIDE;
|
||||
this.paper.drawNew();
|
||||
this.paper.changed();
|
||||
|
@ -1203,7 +1212,7 @@ VectorPaintEditorMorph.prototype.buildContents = function() {
|
|||
|
||||
this.paper.destroy();
|
||||
this.paper = new VectorPaintCanvasMorph(myself.shift);
|
||||
this.paper.setExtent(StageMorph.prototype.dimensions);
|
||||
this.paper.setExtent(this.ide.stage.dimensions);
|
||||
this.body.add(this.paper);
|
||||
|
||||
this.refreshToolButtons();
|
||||
|
|
392
src/store.js
392
src/store.js
|
@ -27,7 +27,7 @@
|
|||
|
||||
prerequisites:
|
||||
--------------
|
||||
needs morphic.js, xml.js, and most of Snap!'s other modules
|
||||
needs morphic.js, xml.js, scenes.js and most of Snap!'s other modules
|
||||
|
||||
|
||||
hierarchy
|
||||
|
@ -49,20 +49,19 @@
|
|||
|
||||
*/
|
||||
|
||||
/*global modules, XML_Element, VariableFrame, StageMorph, SpriteMorph,
|
||||
WatcherMorph, Point, CustomBlockDefinition, Context, ReporterBlockMorph,
|
||||
/*global modules, XML_Element, VariableFrame, StageMorph, SpriteMorph, console,
|
||||
WatcherMorph, Point, CustomBlockDefinition, Context, ReporterBlockMorph, Sound,
|
||||
CommandBlockMorph, detect, CustomCommandBlockMorph, CustomReporterBlockMorph,
|
||||
Color, List, newCanvas, Costume, Sound, Audio, IDE_Morph, ScriptsMorph,
|
||||
Color, List, newCanvas, Costume, Audio, IDE_Morph, ScriptsMorph, ArgLabelMorph,
|
||||
BlockMorph, ArgMorph, InputSlotMorph, TemplateSlotMorph, CommandSlotMorph,
|
||||
FunctionSlotMorph, MultiArgMorph, ColorSlotMorph, nop, CommentMorph, isNil,
|
||||
localize, sizeOf, ArgLabelMorph, SVG_Costume, MorphicPreferences, Process,
|
||||
SyntaxElementMorph, Variable, isSnapObject, console, BooleanSlotMorph,
|
||||
normalizeCanvas, contains*/
|
||||
localize, SVG_Costume, MorphicPreferences, Process, isSnapObject, Variable,
|
||||
SyntaxElementMorph, BooleanSlotMorph, normalizeCanvas, contains, Scene,
|
||||
Project*/
|
||||
|
||||
// Global stuff ////////////////////////////////////////////////////////
|
||||
|
||||
modules.store = '2021-June-24';
|
||||
|
||||
modules.store = '2021-July-02';
|
||||
|
||||
// XML_Serializer ///////////////////////////////////////////////////////
|
||||
/*
|
||||
|
@ -78,6 +77,7 @@ modules.store = '2021-June-24';
|
|||
function XML_Serializer() {
|
||||
this.contents = [];
|
||||
this.media = [];
|
||||
this.root = {};
|
||||
this.isCollectingMedia = false;
|
||||
this.isExportingBlocksLibrary = false;
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ function XML_Serializer() {
|
|||
XML_Serializer.prototype.idProperty = 'serializationID';
|
||||
XML_Serializer.prototype.mediaIdProperty = 'serializationMediaID';
|
||||
XML_Serializer.prototype.mediaDetectionProperty = 'isMedia';
|
||||
XML_Serializer.prototype.version = 1; // increment on structural change
|
||||
XML_Serializer.prototype.version = 2; // increment on structural change
|
||||
|
||||
// XML_Serializer accessing:
|
||||
|
||||
|
@ -109,6 +109,9 @@ XML_Serializer.prototype.store = function (object, mediaID) {
|
|||
// when debugging, be sure to throw an error at this point
|
||||
return '';
|
||||
}
|
||||
if (object instanceof Scene) {
|
||||
this.root = object;
|
||||
}
|
||||
if (this.isCollectingMedia && object[this.mediaDetectionProperty]) {
|
||||
this.addMedia(object, mediaID);
|
||||
return this.format(
|
||||
|
@ -174,6 +177,7 @@ XML_Serializer.prototype.flush = function () {
|
|||
// private - free all objects and empty my contents
|
||||
this.contents.forEach(obj => delete obj[this.idProperty]);
|
||||
this.contents = [];
|
||||
this.root = {};
|
||||
};
|
||||
|
||||
XML_Serializer.prototype.flushMedia = function () {
|
||||
|
@ -247,7 +251,7 @@ SnapSerializer.uber = XML_Serializer.prototype;
|
|||
|
||||
// SnapSerializer constants:
|
||||
|
||||
SnapSerializer.prototype.app = 'Snap! 6, https://snap.berkeley.edu';
|
||||
SnapSerializer.prototype.app = 'Snap! 7dev, https://snap.berkeley.edu';
|
||||
|
||||
SnapSerializer.prototype.thumbnailSize = new Point(160, 120);
|
||||
|
||||
|
@ -279,7 +283,7 @@ function SnapSerializer() {
|
|||
// SnapSerializer initialization:
|
||||
|
||||
SnapSerializer.prototype.init = function () {
|
||||
this.project = {};
|
||||
this.scene = new Scene();
|
||||
this.objects = {};
|
||||
this.mediaDict = {};
|
||||
};
|
||||
|
@ -316,7 +320,9 @@ SnapSerializer.prototype.loadProjectModel = function (xmlNode, ide, remixID) {
|
|||
// show a warning if the origin apps differ
|
||||
|
||||
var appInfo = xmlNode.attributes.app,
|
||||
app = appInfo ? appInfo.split(' ')[0] : null;
|
||||
app = appInfo ? appInfo.split(' ')[0] : null,
|
||||
scenesModel = xmlNode.childNamed('scenes'),
|
||||
project = new Project();
|
||||
|
||||
if (ide && app && app !== this.app.split(' ')[0]) {
|
||||
ide.inform(
|
||||
|
@ -326,18 +332,28 @@ SnapSerializer.prototype.loadProjectModel = function (xmlNode, ide, remixID) {
|
|||
'\n\nand may be incompatible or fail to load here.'
|
||||
);
|
||||
}
|
||||
return this.rawLoadProjectModel(xmlNode, remixID);
|
||||
if (scenesModel) {
|
||||
if (scenesModel.attributes.select) {
|
||||
project.sceneIdx = +scenesModel.attributes.select;
|
||||
}
|
||||
scenesModel.childrenNamed('scene').forEach(model =>
|
||||
project.scenes.add(this.loadScene(model))
|
||||
);
|
||||
} else {
|
||||
project.scenes.add(this.loadScene(xmlNode, remixID));
|
||||
}
|
||||
return project.initialize();
|
||||
};
|
||||
|
||||
SnapSerializer.prototype.rawLoadProjectModel = function (xmlNode, remixID) {
|
||||
SnapSerializer.prototype.loadScene = function (xmlNode, remixID) {
|
||||
// private
|
||||
var project = {sprites: {}},
|
||||
var scene = new Scene(),
|
||||
model,
|
||||
nameID;
|
||||
|
||||
this.project = project;
|
||||
this.scene = scene;
|
||||
|
||||
model = {project: xmlNode };
|
||||
model = {scene: xmlNode };
|
||||
if (+xmlNode.attributes.version > this.version) {
|
||||
throw 'Project uses newer version of Serializer';
|
||||
}
|
||||
|
@ -345,8 +361,8 @@ SnapSerializer.prototype.rawLoadProjectModel = function (xmlNode, remixID) {
|
|||
/* Project Info */
|
||||
|
||||
this.objects = {};
|
||||
project.name = model.project.attributes.name;
|
||||
if (!project.name) {
|
||||
scene.name = model.scene.attributes.name;
|
||||
if (!scene.name) {
|
||||
nameID = 1;
|
||||
while (
|
||||
Object.prototype.hasOwnProperty.call(
|
||||
|
@ -356,138 +372,140 @@ SnapSerializer.prototype.rawLoadProjectModel = function (xmlNode, remixID) {
|
|||
) {
|
||||
nameID += 1;
|
||||
}
|
||||
project.name = 'Untitled ' + nameID;
|
||||
scene.name = 'Untitled ' + nameID;
|
||||
}
|
||||
model.notes = model.project.childNamed('notes');
|
||||
model.notes = model.scene.childNamed('notes');
|
||||
if (model.notes) {
|
||||
project.notes = model.notes.contents;
|
||||
scene.notes = model.notes.contents;
|
||||
}
|
||||
model.globalVariables = model.project.childNamed('variables');
|
||||
project.globalVariables = new VariableFrame();
|
||||
model.globalVariables = model.scene.childNamed('variables');
|
||||
|
||||
scene.unifiedPalette = model.scene.attributes.unifiedPalette === 'true';
|
||||
|
||||
/* Stage */
|
||||
|
||||
model.stage = model.project.require('stage');
|
||||
model.stage = model.scene.require('stage');
|
||||
StageMorph.prototype.frameRate = 0;
|
||||
project.stage = new StageMorph(project.globalVariables);
|
||||
project.stage.remixID = remixID;
|
||||
scene.stage.remixID = remixID;
|
||||
|
||||
if (Object.prototype.hasOwnProperty.call(
|
||||
model.stage.attributes,
|
||||
'id'
|
||||
)) {
|
||||
this.objects[model.stage.attributes.id] = project.stage;
|
||||
this.objects[model.stage.attributes.id] = scene.stage;
|
||||
}
|
||||
if (model.stage.attributes.name) {
|
||||
project.stage.name = model.stage.attributes.name;
|
||||
scene.stage.name = model.stage.attributes.name;
|
||||
}
|
||||
if (model.stage.attributes.color) {
|
||||
project.stage.color = this.loadColor(model.stage.attributes.color);
|
||||
project.stage.cachedHSV = project.stage.color.hsv();
|
||||
scene.stage.color = this.loadColor(model.stage.attributes.color);
|
||||
scene.stage.cachedHSV = scene.stage.color.hsv();
|
||||
}
|
||||
if (model.stage.attributes.scheduled === 'true') {
|
||||
project.stage.fps = 30;
|
||||
scene.stage.fps = 30;
|
||||
StageMorph.prototype.frameRate = 30;
|
||||
}
|
||||
if (model.stage.attributes.volume) {
|
||||
project.stage.volume = +model.stage.attributes.volume;
|
||||
scene.stage.volume = +model.stage.attributes.volume;
|
||||
}
|
||||
if (model.stage.attributes.pan) {
|
||||
project.stage.pan = +model.stage.attributes.pan;
|
||||
scene.stage.pan = +model.stage.attributes.pan;
|
||||
}
|
||||
if (model.stage.attributes.penlog) {
|
||||
StageMorph.prototype.enablePenLogging =
|
||||
scene.enablePenLogging =
|
||||
(model.stage.attributes.penlog === 'true');
|
||||
}
|
||||
|
||||
model.pentrails = model.stage.childNamed('pentrails');
|
||||
if (model.pentrails) {
|
||||
project.pentrails = new Image();
|
||||
project.pentrails.onload = function () {
|
||||
if (project.stage.trailsCanvas) { // work-around a bug in FF
|
||||
normalizeCanvas(project.stage.trailsCanvas);
|
||||
var context = project.stage.trailsCanvas.getContext('2d');
|
||||
context.drawImage(project.pentrails, 0, 0);
|
||||
project.stage.changed();
|
||||
scene.pentrails = new Image();
|
||||
scene.pentrails.onload = function () {
|
||||
if (scene.stage.trailsCanvas) { // work-around a bug in FF
|
||||
normalizeCanvas(scene.stage.trailsCanvas);
|
||||
var context = scene.stage.trailsCanvas.getContext('2d');
|
||||
context.drawImage(scene.pentrails, 0, 0);
|
||||
scene.stage.changed();
|
||||
}
|
||||
};
|
||||
project.pentrails.src = model.pentrails.contents;
|
||||
scene.pentrails.src = model.pentrails.contents;
|
||||
}
|
||||
project.stage.setTempo(model.stage.attributes.tempo);
|
||||
StageMorph.prototype.dimensions = new Point(480, 360);
|
||||
scene.stage.setTempo(model.stage.attributes.tempo);
|
||||
if (model.stage.attributes.width) {
|
||||
StageMorph.prototype.dimensions.x =
|
||||
scene.stage.dimensions.x =
|
||||
Math.max(+model.stage.attributes.width, 240);
|
||||
}
|
||||
if (model.stage.attributes.height) {
|
||||
StageMorph.prototype.dimensions.y =
|
||||
scene.stage.dimensions.y =
|
||||
Math.max(+model.stage.attributes.height, 180);
|
||||
}
|
||||
project.stage.setExtent(StageMorph.prototype.dimensions);
|
||||
SpriteMorph.prototype.useFlatLineEnds =
|
||||
scene.stage.setExtent(scene.stage.dimensions);
|
||||
scene.useFlatLineEnds =
|
||||
model.stage.attributes.lines === 'flat';
|
||||
BooleanSlotMorph.prototype.isTernary =
|
||||
model.stage.attributes.ternary !== 'false';
|
||||
Process.prototype.enableHyperOps =
|
||||
scene.enableHyperOps =
|
||||
model.stage.attributes.hyperops !== 'false';
|
||||
project.stage.isThreadSafe =
|
||||
scene.stage.isThreadSafe =
|
||||
model.stage.attributes.threadsafe === 'true';
|
||||
StageMorph.prototype.enableCodeMapping =
|
||||
scene.enableCodeMapping =
|
||||
model.stage.attributes.codify === 'true';
|
||||
StageMorph.prototype.enableInheritance =
|
||||
scene.enableInheritance =
|
||||
model.stage.attributes.inheritance !== 'false';
|
||||
StageMorph.prototype.enableSublistIDs =
|
||||
scene.enableSublistIDs =
|
||||
model.stage.attributes.sublistIDs === 'true';
|
||||
|
||||
model.hiddenPrimitives = model.project.childNamed('hidden');
|
||||
model.hiddenPrimitives = model.scene.childNamed('hidden');
|
||||
if (model.hiddenPrimitives) {
|
||||
model.hiddenPrimitives.contents.split(' ').forEach(
|
||||
sel => {
|
||||
if (sel) {
|
||||
StageMorph.prototype.hiddenPrimitives[sel] = true;
|
||||
scene.hiddenPrimitives[sel] = true;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
model.codeHeaders = model.project.childNamed('headers');
|
||||
model.codeHeaders = model.scene.childNamed('headers');
|
||||
if (model.codeHeaders) {
|
||||
model.codeHeaders.children.forEach(
|
||||
xml => StageMorph.prototype.codeHeaders[xml.tag] = xml.contents
|
||||
xml => scene.codeHeaders[xml.tag] = xml.contents
|
||||
);
|
||||
}
|
||||
|
||||
model.codeMappings = model.project.childNamed('code');
|
||||
model.codeMappings = model.scene.childNamed('code');
|
||||
if (model.codeMappings) {
|
||||
model.codeMappings.children.forEach(
|
||||
xml => StageMorph.prototype.codeMappings[xml.tag] = xml.contents
|
||||
xml => scene.codeMappings[xml.tag] = xml.contents
|
||||
);
|
||||
}
|
||||
|
||||
model.globalBlocks = model.project.childNamed('blocks');
|
||||
model.globalBlocks = model.scene.childNamed('blocks');
|
||||
if (model.globalBlocks) {
|
||||
this.loadCustomBlocks(project.stage, model.globalBlocks, true);
|
||||
this.loadCustomBlocks(scene.stage, model.globalBlocks, true);
|
||||
this.populateCustomBlocks(
|
||||
project.stage,
|
||||
scene.stage,
|
||||
model.globalBlocks,
|
||||
true
|
||||
);
|
||||
}
|
||||
this.loadObject(project.stage, model.stage);
|
||||
this.loadObject(scene.stage, model.stage);
|
||||
|
||||
/* Sprites */
|
||||
|
||||
model.sprites = model.stage.require('sprites');
|
||||
project.sprites[project.stage.name] = project.stage;
|
||||
|
||||
if (model.sprites.attributes.select) {
|
||||
scene.spriteIdx = +model.sprites.attributes.select;
|
||||
}
|
||||
scene.spritesDict[scene.stage.name] = scene.stage;
|
||||
model.sprites.childrenNamed('sprite').forEach(
|
||||
model => this.loadValue(model)
|
||||
);
|
||||
|
||||
// restore inheritance and nesting associations
|
||||
this.project.stage.children.forEach(sprite => {
|
||||
this.scene.stage.children.forEach(sprite => {
|
||||
var exemplar, anchor;
|
||||
if (sprite.inheritanceInfo) { // only sprites can inherit
|
||||
exemplar = this.project.sprites[
|
||||
exemplar = this.scene.spritesDict[
|
||||
sprite.inheritanceInfo.exemplar
|
||||
];
|
||||
if (exemplar) {
|
||||
|
@ -497,14 +515,14 @@ SnapSerializer.prototype.rawLoadProjectModel = function (xmlNode, remixID) {
|
|||
sprite.updatePropagationCache();
|
||||
}
|
||||
if (sprite.nestingInfo) { // only sprites may have nesting info
|
||||
anchor = this.project.sprites[sprite.nestingInfo.anchor];
|
||||
anchor = this.scene.spritesDict[sprite.nestingInfo.anchor];
|
||||
if (anchor) {
|
||||
anchor.attachPart(sprite);
|
||||
}
|
||||
sprite.rotatesWithAnchor = (sprite.nestingInfo.synch === 'true');
|
||||
}
|
||||
});
|
||||
this.project.stage.children.forEach(sprite => {
|
||||
this.scene.stage.children.forEach(sprite => {
|
||||
var costume;
|
||||
if (sprite.nestingInfo) { // only sprites may have nesting info
|
||||
sprite.nestingScale = +(sprite.nestingInfo.scale || sprite.scale);
|
||||
|
@ -541,7 +559,7 @@ SnapSerializer.prototype.rawLoadProjectModel = function (xmlNode, remixID) {
|
|||
|
||||
if (model.globalVariables) {
|
||||
this.loadVariables(
|
||||
project.globalVariables,
|
||||
scene.globalVariables,
|
||||
model.globalVariables
|
||||
);
|
||||
}
|
||||
|
@ -557,7 +575,7 @@ SnapSerializer.prototype.rawLoadProjectModel = function (xmlNode, remixID) {
|
|||
target = Object.prototype.hasOwnProperty.call(
|
||||
model.attributes,
|
||||
'scope'
|
||||
) ? project.sprites[model.attributes.scope] : null;
|
||||
) ? scene.spritesDict[model.attributes.scope] : null;
|
||||
|
||||
// determine whether the watcher is hidden, slightly
|
||||
// complicated to retain backward compatibility
|
||||
|
@ -575,7 +593,7 @@ SnapSerializer.prototype.rawLoadProjectModel = function (xmlNode, remixID) {
|
|||
watcher = new WatcherMorph(
|
||||
model.attributes['var'],
|
||||
color,
|
||||
isNil(target) ? project.globalVariables
|
||||
isNil(target) ? scene.globalVariables
|
||||
: target.variables,
|
||||
model.attributes['var'],
|
||||
hidden
|
||||
|
@ -595,12 +613,12 @@ SnapSerializer.prototype.rawLoadProjectModel = function (xmlNode, remixID) {
|
|||
watcher.setSliderMax(model.attributes.max || '100', true);
|
||||
}
|
||||
watcher.setPosition(
|
||||
project.stage.topLeft().add(new Point(
|
||||
scene.stage.topLeft().add(new Point(
|
||||
+model.attributes.x || 0,
|
||||
+model.attributes.y || 0
|
||||
))
|
||||
);
|
||||
project.stage.add(watcher);
|
||||
scene.stage.add(watcher);
|
||||
watcher.onNextStep = function () {this.currentValue = null; };
|
||||
|
||||
// set watcher's contentsMorph's extent if it is showing a list and
|
||||
|
@ -621,25 +639,22 @@ SnapSerializer.prototype.rawLoadProjectModel = function (xmlNode, remixID) {
|
|||
});
|
||||
|
||||
// clear sprites' inherited methods caches, if any
|
||||
this.project.stage.children.forEach(
|
||||
this.scene.stage.children.forEach(
|
||||
sprite => sprite.inheritedMethodsCache = []
|
||||
);
|
||||
|
||||
this.objects = {};
|
||||
return project;
|
||||
return scene.initialize();
|
||||
};
|
||||
|
||||
SnapSerializer.prototype.loadBlocks = function (xmlString, targetStage) {
|
||||
// public - answer a new Array of custom block definitions
|
||||
// represented by the given XML String
|
||||
var stage = new StageMorph(),
|
||||
model;
|
||||
var stage, model;
|
||||
|
||||
this.project = {
|
||||
stage: stage,
|
||||
sprites: {},
|
||||
targetStage: targetStage // for secondary custom block def look-up
|
||||
};
|
||||
this.scene = new Scene();
|
||||
this.scene.targetStage = targetStage; // for secondary block def look-up
|
||||
stage = this.scene.stage;
|
||||
model = this.parse(xmlString);
|
||||
if (+model.attributes.version > this.version) {
|
||||
throw 'Module uses newer version of Serializer';
|
||||
|
@ -653,36 +668,33 @@ SnapSerializer.prototype.loadBlocks = function (xmlString, targetStage) {
|
|||
this.objects = {};
|
||||
stage.globalBlocks.forEach(def => def.receiver = null);
|
||||
this.objects = {};
|
||||
this.project = {};
|
||||
this.scene = new Scene();
|
||||
this.mediaDict = {};
|
||||
return stage.globalBlocks;
|
||||
};
|
||||
|
||||
SnapSerializer.prototype.loadSprites = function (xmlString, ide) {
|
||||
// public - import a set of sprites represented by xmlString
|
||||
// into the current project of the ide
|
||||
var model, project;
|
||||
// into the current scene of the ide
|
||||
var model, scene;
|
||||
|
||||
project = this.project = {
|
||||
globalVariables: ide.globalVariables,
|
||||
stage: ide.stage,
|
||||
sprites: {}
|
||||
};
|
||||
project.sprites[project.stage.name] = project.stage;
|
||||
this.scene = new Scene(ide.stage);
|
||||
scene = this.scene;
|
||||
scene.spritesDict[scene.stage.name] = scene.stage;
|
||||
|
||||
model = this.parse(xmlString);
|
||||
if (+model.attributes.version > this.version) {
|
||||
throw 'Module uses newer version of Serializer';
|
||||
}
|
||||
model.childrenNamed('sprite').forEach(model => {
|
||||
var sprite = new SpriteMorph(project.globalVariables);
|
||||
var sprite = new SpriteMorph(scene.globalVariables);
|
||||
|
||||
if (model.attributes.id) {
|
||||
this.objects[model.attributes.id] = sprite;
|
||||
}
|
||||
if (model.attributes.name) {
|
||||
sprite.name = ide.newSpriteName(model.attributes.name);
|
||||
project.sprites[sprite.name] = sprite;
|
||||
scene.spritesDict[sprite.name] = sprite;
|
||||
}
|
||||
if (model.attributes.color) {
|
||||
sprite.color = this.loadColor(model.attributes.color);
|
||||
|
@ -697,7 +709,7 @@ SnapSerializer.prototype.loadSprites = function (xmlString, ide) {
|
|||
if (model.attributes.pan) {
|
||||
sprite.pan = +model.attributes.pan;
|
||||
}
|
||||
project.stage.add(sprite);
|
||||
scene.stage.add(sprite);
|
||||
ide.sprites.add(sprite);
|
||||
sprite.scale = parseFloat(model.attributes.scale || '1');
|
||||
sprite.rotationStyle = parseFloat(
|
||||
|
@ -713,10 +725,10 @@ SnapSerializer.prototype.loadSprites = function (xmlString, ide) {
|
|||
});
|
||||
|
||||
// restore inheritance and nesting associations
|
||||
project.stage.children.forEach(sprite => {
|
||||
scene.stage.children.forEach(sprite => {
|
||||
var exemplar, anchor;
|
||||
if (sprite.inheritanceInfo) { // only sprites can inherit
|
||||
exemplar = project.sprites[
|
||||
exemplar = scene.spritesDict[
|
||||
sprite.inheritanceInfo.exemplar
|
||||
];
|
||||
if (exemplar) {
|
||||
|
@ -724,14 +736,14 @@ SnapSerializer.prototype.loadSprites = function (xmlString, ide) {
|
|||
}
|
||||
}
|
||||
if (sprite.nestingInfo) { // only sprites may have nesting info
|
||||
anchor = project.sprites[sprite.nestingInfo.anchor];
|
||||
anchor = scene.spritesDict[sprite.nestingInfo.anchor];
|
||||
if (anchor) {
|
||||
anchor.attachPart(sprite);
|
||||
}
|
||||
sprite.rotatesWithAnchor = (sprite.nestingInfo.synch === 'true');
|
||||
}
|
||||
});
|
||||
project.stage.children.forEach(sprite => {
|
||||
scene.stage.children.forEach(sprite => {
|
||||
delete sprite.inheritanceInfo;
|
||||
if (sprite.nestingInfo) { // only sprites may have nesting info
|
||||
sprite.nestingScale = +(sprite.nestingInfo.scale || sprite.scale);
|
||||
|
@ -740,7 +752,7 @@ SnapSerializer.prototype.loadSprites = function (xmlString, ide) {
|
|||
});
|
||||
|
||||
this.objects = {};
|
||||
this.project = {};
|
||||
this.scene = new Scene();
|
||||
this.mediaDict = {};
|
||||
|
||||
ide.stage.fixLayout();
|
||||
|
@ -1111,10 +1123,10 @@ SnapSerializer.prototype.loadScript = function (model, object) {
|
|||
var topBlock, block, nextBlock;
|
||||
|
||||
// Check whether we're importing a single script, not a script as part of a
|
||||
// whole project
|
||||
if (!this.project.stage) {
|
||||
this.project.stage = object.parentThatIsA(StageMorph);
|
||||
this.project.targetStage = this.project.stage;
|
||||
// whole scene
|
||||
if (!this.scene.stage) {
|
||||
this.scene.stage = object.parentThatIsA(StageMorph);
|
||||
this.scene.targetStage = this.scene.stage;
|
||||
}
|
||||
|
||||
model.children.forEach(child => {
|
||||
|
@ -1174,15 +1186,15 @@ SnapSerializer.prototype.loadBlock = function (model, isReporter, object) {
|
|||
}
|
||||
} else if (model.tag === 'custom-block') {
|
||||
isGlobal = model.attributes.scope ? false : true;
|
||||
receiver = isGlobal ? this.project.stage : object;
|
||||
receiver = isGlobal ? this.scene.stage : object;
|
||||
if (isGlobal) {
|
||||
info = detect(
|
||||
receiver.globalBlocks,
|
||||
block => block.blockSpec() === model.attributes.s
|
||||
);
|
||||
if (!info && this.project.targetStage) { // importing block files
|
||||
if (!info && this.scene.targetStage) { // importing block files
|
||||
info = detect(
|
||||
this.project.targetStage.globalBlocks,
|
||||
this.scene.targetStage.globalBlocks,
|
||||
block => block.blockSpec() === model.attributes.s
|
||||
);
|
||||
}
|
||||
|
@ -1399,13 +1411,13 @@ SnapSerializer.prototype.loadValue = function (model, object) {
|
|||
});
|
||||
return v;
|
||||
case 'sprite':
|
||||
v = new SpriteMorph(this.project.globalVariables);
|
||||
v = new SpriteMorph(this.scene.globalVariables);
|
||||
if (model.attributes.id) {
|
||||
this.objects[model.attributes.id] = v;
|
||||
}
|
||||
if (model.attributes.name) {
|
||||
v.name = model.attributes.name;
|
||||
this.project.sprites[model.attributes.name] = v;
|
||||
this.scene.spritesDict[model.attributes.name] = v;
|
||||
}
|
||||
if (model.attributes.idx) {
|
||||
v.idx = +model.attributes.idx;
|
||||
|
@ -1423,7 +1435,7 @@ SnapSerializer.prototype.loadValue = function (model, object) {
|
|||
if (model.attributes.pan) {
|
||||
v.pan = +model.attributes.pan;
|
||||
}
|
||||
this.project.stage.add(v);
|
||||
this.scene.stage.add(v);
|
||||
v.scale = parseFloat(model.attributes.scale || '1');
|
||||
v.rotationStyle = parseFloat(
|
||||
model.attributes.rotation || '1'
|
||||
|
@ -1605,48 +1617,6 @@ SnapSerializer.prototype.loadColor = function (colorString) {
|
|||
);
|
||||
};
|
||||
|
||||
SnapSerializer.prototype.openProject = function (project, ide) {
|
||||
var stage = ide.stage,
|
||||
sprites = [],
|
||||
sprite;
|
||||
if (!project || !project.stage) {
|
||||
return;
|
||||
}
|
||||
ide.siblings().forEach(morph =>
|
||||
morph.destroy()
|
||||
);
|
||||
ide.projectName = project.name;
|
||||
ide.projectNotes = project.notes || '';
|
||||
if (ide.globalVariables) {
|
||||
ide.globalVariables = project.globalVariables;
|
||||
}
|
||||
if (stage) {
|
||||
stage.destroy();
|
||||
}
|
||||
ide.add(project.stage);
|
||||
ide.stage = project.stage;
|
||||
sprites = ide.stage.children.filter(
|
||||
child => child instanceof SpriteMorph
|
||||
);
|
||||
sprites.sort((x, y) => x.idx - y.idx);
|
||||
|
||||
ide.sprites = new List(sprites);
|
||||
sprite = sprites[0] || project.stage;
|
||||
|
||||
if (sizeOf(this.mediaDict) > 0) {
|
||||
ide.hasChangedMedia = false;
|
||||
this.mediaDict = {};
|
||||
} else {
|
||||
ide.hasChangedMedia = true;
|
||||
}
|
||||
project.stage.fixLayout();
|
||||
project.stage.pauseGenericHatBlocks();
|
||||
ide.createCorral();
|
||||
ide.selectSprite(sprite);
|
||||
ide.fixLayout();
|
||||
ide.world().keyboardFocus = project.stage;
|
||||
};
|
||||
|
||||
// SnapSerializer XML-representation of objects:
|
||||
|
||||
// Generics
|
||||
|
@ -1658,24 +1628,39 @@ Array.prototype.toXML = function (serializer) {
|
|||
);
|
||||
};
|
||||
|
||||
// Sprites
|
||||
// Scenes & multi-scene projects
|
||||
|
||||
StageMorph.prototype.toXML = function (serializer) {
|
||||
var thumbnail = normalizeCanvas(
|
||||
this.thumbnail(SnapSerializer.prototype.thumbnailSize),
|
||||
true
|
||||
),
|
||||
thumbdata,
|
||||
costumeIdx = this.getCostumeIdx(),
|
||||
ide = this.parentThatIsA(IDE_Morph);
|
||||
Project.prototype.toXML = function (serializer) {
|
||||
var thumbdata;
|
||||
|
||||
// catch cross-origin tainting exception when using SVG costumes
|
||||
// thumb data catch cross-origin tainting exception when using SVG costumes
|
||||
try {
|
||||
thumbdata = thumbnail.toDataURL('image/png');
|
||||
thumbdata = this.thumbnail.toDataURL('image/png');
|
||||
} catch (error) {
|
||||
thumbdata = null;
|
||||
}
|
||||
|
||||
return serializer.format(
|
||||
'<project name="@" app="@" version="@">' +
|
||||
'<notes>$</notes>' +
|
||||
'<thumbnail>$</thumbnail>' +
|
||||
'<scenes select="@">%</scenes>' +
|
||||
'</project>',
|
||||
this.name || localize('Untitled'),
|
||||
serializer.app,
|
||||
serializer.version,
|
||||
this.notes || '',
|
||||
thumbdata,
|
||||
this.scenes.asArray().indexOf(
|
||||
this.currentScene) + 1,
|
||||
serializer.store(this.scenes.itemsArray())
|
||||
);
|
||||
};
|
||||
|
||||
Scene.prototype.toXML = function (serializer) {
|
||||
var tmp = new Scene(),
|
||||
xml;
|
||||
|
||||
function code(key) {
|
||||
var str = '';
|
||||
Object.keys(StageMorph.prototype[key]).forEach(
|
||||
|
@ -1692,12 +1677,43 @@ StageMorph.prototype.toXML = function (serializer) {
|
|||
return str;
|
||||
}
|
||||
|
||||
tmp.captureGlobalSettings();
|
||||
this.applyGlobalSettings();
|
||||
xml = serializer.format(
|
||||
'<scene name="@" unifiedPalette="@">' +
|
||||
'<notes>$</notes>' +
|
||||
'<hidden>$</hidden>' +
|
||||
'<headers>%</headers>' +
|
||||
'<code>%</code>' +
|
||||
'<blocks>%</blocks>' +
|
||||
'<variables>%</variables>' +
|
||||
'%' + // stage
|
||||
'</scene>',
|
||||
this.name || localize('Untitled'),
|
||||
this.unifiedPalette,
|
||||
this.notes || '',
|
||||
Object.keys(StageMorph.prototype.hiddenPrimitives).reduce(
|
||||
(a, b) => a + ' ' + b,
|
||||
''
|
||||
),
|
||||
code('codeHeaders'),
|
||||
code('codeMappings'),
|
||||
serializer.store(this.stage.globalBlocks),
|
||||
serializer.store(this.globalVariables),
|
||||
serializer.store(this.stage)
|
||||
);
|
||||
tmp.applyGlobalSettings();
|
||||
return xml;
|
||||
};
|
||||
|
||||
// Sprites
|
||||
|
||||
StageMorph.prototype.toXML = function (serializer) {
|
||||
var costumeIdx = this.getCostumeIdx();
|
||||
|
||||
this.removeAllClones();
|
||||
return serializer.format(
|
||||
'<project name="@" app="@" version="@">' +
|
||||
'<notes>$</notes>' +
|
||||
'<thumbnail>$</thumbnail>' +
|
||||
'<stage name="@" width="@" height="@" ' +
|
||||
'<stage width="@" height="@" ' +
|
||||
'costume="@" color="@,@,@,@" tempo="@" threadsafe="@" ' +
|
||||
'penlog="@" ' +
|
||||
'%' +
|
||||
|
@ -1716,22 +1732,11 @@ StageMorph.prototype.toXML = function (serializer) {
|
|||
'<sounds>%</sounds>' +
|
||||
'<variables>%</variables>' +
|
||||
'<blocks>%</blocks>' +
|
||||
'<scripts>%</scripts><sprites>%</sprites>' +
|
||||
'</stage>' +
|
||||
'<hidden>$</hidden>' +
|
||||
'<headers>%</headers>' +
|
||||
'<code>%</code>' +
|
||||
'<blocks>%</blocks>' +
|
||||
'<variables>%</variables>' +
|
||||
'</project>',
|
||||
(ide && ide.projectName) ? ide.projectName : localize('Untitled'),
|
||||
serializer.app,
|
||||
serializer.version,
|
||||
(ide && ide.projectNotes) ? ide.projectNotes : '',
|
||||
thumbdata,
|
||||
this.name,
|
||||
StageMorph.prototype.dimensions.x,
|
||||
StageMorph.prototype.dimensions.y,
|
||||
'<scripts>%</scripts>' +
|
||||
'<sprites select="@">%</sprites>' +
|
||||
'</stage>',
|
||||
this.dimensions.x,
|
||||
this.dimensions.y,
|
||||
costumeIdx,
|
||||
this.color.r,
|
||||
this.color.g,
|
||||
|
@ -1763,23 +1768,14 @@ StageMorph.prototype.toXML = function (serializer) {
|
|||
serializer.store(this.variables),
|
||||
serializer.store(this.customBlocks),
|
||||
serializer.store(this.scripts),
|
||||
serializer.store(this.children),
|
||||
Object.keys(StageMorph.prototype.hiddenPrimitives).reduce(
|
||||
(a, b) => a + ' ' + b,
|
||||
''
|
||||
),
|
||||
code('codeHeaders'),
|
||||
code('codeMappings'),
|
||||
serializer.store(this.globalBlocks),
|
||||
(ide && ide.globalVariables) ?
|
||||
serializer.store(ide.globalVariables) : ''
|
||||
serializer.root.sprites.asArray().indexOf(
|
||||
serializer.root.currentSprite) + 1,
|
||||
serializer.store(this.children)
|
||||
);
|
||||
};
|
||||
|
||||
SpriteMorph.prototype.toXML = function (serializer) {
|
||||
var stage = this.parentThatIsA(StageMorph),
|
||||
ide = stage ? stage.parentThatIsA(IDE_Morph) : null,
|
||||
idx = ide ? ide.sprites.asArray().indexOf(this) + 1 : 0,
|
||||
var idx = serializer.root.sprites.asArray().indexOf(this) + 1,
|
||||
costumeIdx = this.getCostumeIdx(),
|
||||
noCostumes = this.inheritsAttribute('costumes'),
|
||||
noSounds = this.inheritsAttribute('sounds'),
|
||||
|
|
|
@ -4657,6 +4657,55 @@ Process.prototype.goToLayer = function (name) {
|
|||
}
|
||||
};
|
||||
|
||||
// Process scene primitives
|
||||
|
||||
Process.prototype.doSwitchToScene = function (id) {
|
||||
var rcvr = this.blockReceiver(),
|
||||
idx = 0,
|
||||
ide, scenes, num, scene;
|
||||
|
||||
this.assertAlive(rcvr);
|
||||
ide = rcvr.parentThatIsA(IDE_Morph);
|
||||
scenes = ide.scenes;
|
||||
|
||||
if (id instanceof Array) { // special named indices
|
||||
switch (this.inputOption(id)) {
|
||||
case 'next':
|
||||
idx = scenes.indexOf(ide.scene) + 1;
|
||||
if (idx > scenes.length()) {
|
||||
idx = 1;
|
||||
}
|
||||
break;
|
||||
case 'previous':
|
||||
idx = scenes.indexOf(ide.scene) - 1;
|
||||
if (idx < 1) {
|
||||
idx = scenes.length();
|
||||
}
|
||||
break;
|
||||
case 'last':
|
||||
idx = scenes.length();
|
||||
break;
|
||||
case 'random':
|
||||
idx = this.reportBasicRandom(1, scenes.length());
|
||||
break;
|
||||
}
|
||||
ide.switchToScene(scenes.at(idx));
|
||||
return;
|
||||
}
|
||||
|
||||
scene = detect(scenes.itemsArray(), scn => scn.name === id);
|
||||
if (scene === null) {
|
||||
num = parseFloat(id);
|
||||
if (isNaN(num)) {
|
||||
return;
|
||||
}
|
||||
scene = scenes.at(num);
|
||||
}
|
||||
|
||||
ide.switchToScene(scene);
|
||||
};
|
||||
|
||||
|
||||
// Process color primitives
|
||||
|
||||
Process.prototype.setHSVA = function (name, num) {
|
||||
|
|
Ładowanie…
Reference in New Issue