Modularize remaining objects with static methods

This commit is contained in:
Tim Mickel 2016-01-21 15:10:18 -05:00
parent 55d8b40691
commit bf07d98ccd
15 changed files with 5662 additions and 5463 deletions

View file

@ -1,306 +1,331 @@
var BlockSpecs = function () {};
import Localization from '../../utils/Localization';
import IO from '../../iPad/IO';
BlockSpecs.loadCount = 0;
BlockSpecs.loadassets = {};
BlockSpecs.fontwhite = '#f2f3f2';
BlockSpecs.fontpink = '#ff8ae9';
BlockSpecs.fontdarkgray = '#6d6e6c';
BlockSpecs.fontblack = '#1b2a34';
BlockSpecs.fontyellow = '#ffdd33';
BlockSpecs.fontdarkgreen = '#287f46';
BlockSpecs.fontpurple = '#8f56e3';
BlockSpecs.fontblue = '#0d50ab';
BlockSpecs.fontred = '#c4281b';
BlockSpecs.fontorange = '#da8540';
let loadCount = 0;
BlockSpecs.fontcolors = [BlockSpecs.fontred, BlockSpecs.fontorange, BlockSpecs.fontyellow,
BlockSpecs.fontdarkgreen, BlockSpecs.fontblue, BlockSpecs.fontpink, BlockSpecs.fontpurple,
BlockSpecs.fontwhite, BlockSpecs.fontdarkgray, BlockSpecs.fontblack];
let loadassets = {};
let fontwhite = '#f2f3f2';
let fontpink = '#ff8ae9';
let fontdarkgray = '#6d6e6c';
let fontblack = '#1b2a34';
let fontyellow = '#ffdd33';
let fontdarkgreen = '#287f46';
let fontpurple = '#8f56e3';
let fontblue = '#0d50ab';
let fontred = '#c4281b';
let fontorange = '#da8540';
BlockSpecs.fontsizes = [16, 24, 36, 48, 56, 72];
let fontcolors = [fontred, fontorange, fontyellow,
fontdarkgreen, fontblue, fontpink, fontpurple,
fontwhite, fontdarkgray, fontblack];
BlockSpecs.getshapes = ['LetterGet_Orange', 'LetterGet_Red', 'LetterGet_Yellow', 'LetterGet_Green',
let fontsizes = [16, 24, 36, 48, 56, 72];
let getshapes = ['LetterGet_Orange', 'LetterGet_Red', 'LetterGet_Yellow', 'LetterGet_Green',
'LetterGet_Blue', 'LetterGet_Purple'];
BlockSpecs.sendshapes = ['LetterSend_Orange', 'LetterSend_Red', 'LetterSend_Yellow', 'LetterSend_Green',
let sendshapes = ['LetterSend_Orange', 'LetterSend_Red', 'LetterSend_Yellow', 'LetterSend_Green',
'LetterSend_Blue', 'LetterSend_Purple'];
BlockSpecs.speeds = ['speed0', 'speed1', 'speed2'];
let speeds = ['speed0', 'speed1', 'speed2'];
BlockSpecs.initBlocks = function () {
BlockSpecs.loadassets = new Object();
BlockSpecs.loadGraphics();
BlockSpecs.defs = BlockSpecs.setupBlocksSpecs();
BlockSpecs.palettes = BlockSpecs.setupPalettesDef();
BlockSpecs.categories = BlockSpecs.setupCategories();
if (Settings.edition == 'PBS') {
BlockSpecs.canvasMask = BlockSpecs.getImageFrom('assets/ui/canvasmask', 'svg');
} else {
BlockSpecs.canvasMask = BlockSpecs.getImageFrom('assets/ui/canvasmask');
export default class BlockSpecs {
static get loadCount () {
return loadCount;
}
if (Settings.edition != 'PBS') {
BlockSpecs.projectThumb = BlockSpecs.getImageFrom('assets/lobby/pmask');
static set loadCount (newLoadCount) {
loadCount = newLoadCount;
}
IO.requestFromServer('assets/balloon.svg', BlockSpecs.setBalloon);
BlockSpecs.loadCount++;
};
BlockSpecs.setBalloon = function (str) {
BlockSpecs.loadCount--;
BlockSpecs.balloon = str;
};
BlockSpecs.loadGraphics = function () {
BlockSpecs.mic = BlockSpecs.getImageFrom('assets/ui/recordslot', 'svg');
BlockSpecs.yellowStart = BlockSpecs.getImageFrom('assets/blocks/start', 'svg');
BlockSpecs.yellowStartH = BlockSpecs.getImageFrom('assets/blocks/eh/startH');
BlockSpecs.yellowCmd = BlockSpecs.getImageFrom('assets/blocks/yellowCmd', 'svg');
BlockSpecs.yellowCmdH = BlockSpecs.getImageFrom('assets/blocks/eh/yellowCmdH');
BlockSpecs.redEnd = BlockSpecs.getImageFrom('assets/blocks/endshort', 'svg');
BlockSpecs.redEndH = BlockSpecs.getImageFrom('assets/blocks/eh/stopH');
BlockSpecs.orangeCmd = BlockSpecs.getImageFrom('assets/blocks/flow', 'svg');
BlockSpecs.orangeCmdH = BlockSpecs.getImageFrom('assets/blocks/eh/flowH');
BlockSpecs.limeCmd = BlockSpecs.getImageFrom('assets/blocks/sounds', 'svg');
BlockSpecs.limeCmdH = BlockSpecs.getImageFrom('assets/blocks/eh/soundsH');
BlockSpecs.pinkCmd = BlockSpecs.getImageFrom('assets/blocks/looks', 'svg');
BlockSpecs.pinkCmdH = BlockSpecs.getImageFrom('assets/blocks/eh/looksH');
BlockSpecs.redEndLong = BlockSpecs.getImageFrom('assets/blocks/endlong', 'svg');
BlockSpecs.redEndLongH = BlockSpecs.getImageFrom('assets/blocks/eh/stoplongH');
BlockSpecs.cShape = BlockSpecs.getImageFrom('assets/blocks/repeat');
BlockSpecs.cShapeH = BlockSpecs.getImageFrom('assets/blocks/eh/repeatH');
BlockSpecs.blueCmd = BlockSpecs.getImageFrom('assets/blocks/blueCmd', 'svg');
BlockSpecs.blueCmdH = BlockSpecs.getImageFrom('assets/blocks/eh/blueCmdH');
BlockSpecs.textfieldimg = BlockSpecs.getImageFrom('assets/misc/Text-01');
BlockSpecs.numfieldimg = BlockSpecs.getImageFrom('assets/misc/Number-01');
BlockSpecs.pressbutton = BlockSpecs.getImageFrom('assets/misc/pushbutton-01', 'svg');
BlockSpecs.pressbuttonSmall = BlockSpecs.getImageFrom('assets/misc/pushbutton', 'svg');
BlockSpecs.caretrepeat = BlockSpecs.getImageFrom('assets/blocks/caretrepeat');
BlockSpecs.cmdS = BlockSpecs.getImageFrom('assets/blocks/shadowCmd', 'svg');
BlockSpecs.startS = BlockSpecs.getImageFrom('assets/blocks/shadowStart', 'svg');
BlockSpecs.endS = BlockSpecs.getImageFrom('assets/blocks/shadowEndShort', 'svg');
BlockSpecs.endLongS = BlockSpecs.getImageFrom('assets/blocks/shadowEndLong', 'svg');
BlockSpecs.repeatS = BlockSpecs.getImageFrom('assets/blocks/shadowRepeat');
};
BlockSpecs.getImageFrom = function (url, ext) {
var img = document.createElement('img');
img.src = url + (ext ? '.' + ext : '.png');
if (!img.complete) {
BlockSpecs.loadassets[img.src] = img;
BlockSpecs.loadCount++;
img.onload = function () {
delete BlockSpecs.loadassets[img.src];
BlockSpecs.loadCount--;
};
static get fontcolors () {
return fontcolors;
}
static get fontsizes () {
return fontsizes;
}
static get speeds () {
return speeds;
}
static initBlocks () {
loadassets = new Object();
BlockSpecs.loadGraphics();
BlockSpecs.defs = BlockSpecs.setupBlocksSpecs();
BlockSpecs.palettes = BlockSpecs.setupPalettesDef();
BlockSpecs.categories = BlockSpecs.setupCategories();
if (Settings.edition == 'PBS') {
BlockSpecs.canvasMask = BlockSpecs.getImageFrom('assets/ui/canvasmask', 'svg');
} else {
BlockSpecs.canvasMask = BlockSpecs.getImageFrom('assets/ui/canvasmask');
}
if (Settings.edition != 'PBS') {
BlockSpecs.projectThumb = BlockSpecs.getImageFrom('assets/lobby/pmask');
}
IO.requestFromServer('assets/balloon.svg', BlockSpecs.setBalloon);
loadCount++;
}
static setBalloon (str) {
loadCount--;
BlockSpecs.balloon = str;
}
return img;
};
BlockSpecs.refreshLoading = function () {
for (var key in BlockSpecs.loadassets) {
if (BlockSpecs.loadassets[key].complete) {
BlockSpecs.loadCount--;
static loadGraphics () {
BlockSpecs.mic = BlockSpecs.getImageFrom('assets/ui/recordslot', 'svg');
BlockSpecs.yellowStart = BlockSpecs.getImageFrom('assets/blocks/start', 'svg');
BlockSpecs.yellowStartH = BlockSpecs.getImageFrom('assets/blocks/eh/startH');
BlockSpecs.yellowCmd = BlockSpecs.getImageFrom('assets/blocks/yellowCmd', 'svg');
BlockSpecs.yellowCmdH = BlockSpecs.getImageFrom('assets/blocks/eh/yellowCmdH');
BlockSpecs.redEnd = BlockSpecs.getImageFrom('assets/blocks/endshort', 'svg');
BlockSpecs.redEndH = BlockSpecs.getImageFrom('assets/blocks/eh/stopH');
BlockSpecs.orangeCmd = BlockSpecs.getImageFrom('assets/blocks/flow', 'svg');
BlockSpecs.orangeCmdH = BlockSpecs.getImageFrom('assets/blocks/eh/flowH');
BlockSpecs.limeCmd = BlockSpecs.getImageFrom('assets/blocks/sounds', 'svg');
BlockSpecs.limeCmdH = BlockSpecs.getImageFrom('assets/blocks/eh/soundsH');
BlockSpecs.pinkCmd = BlockSpecs.getImageFrom('assets/blocks/looks', 'svg');
BlockSpecs.pinkCmdH = BlockSpecs.getImageFrom('assets/blocks/eh/looksH');
BlockSpecs.redEndLong = BlockSpecs.getImageFrom('assets/blocks/endlong', 'svg');
BlockSpecs.redEndLongH = BlockSpecs.getImageFrom('assets/blocks/eh/stoplongH');
BlockSpecs.cShape = BlockSpecs.getImageFrom('assets/blocks/repeat');
BlockSpecs.cShapeH = BlockSpecs.getImageFrom('assets/blocks/eh/repeatH');
BlockSpecs.blueCmd = BlockSpecs.getImageFrom('assets/blocks/blueCmd', 'svg');
BlockSpecs.blueCmdH = BlockSpecs.getImageFrom('assets/blocks/eh/blueCmdH');
BlockSpecs.textfieldimg = BlockSpecs.getImageFrom('assets/misc/Text-01');
BlockSpecs.numfieldimg = BlockSpecs.getImageFrom('assets/misc/Number-01');
BlockSpecs.pressbutton = BlockSpecs.getImageFrom('assets/misc/pushbutton-01', 'svg');
BlockSpecs.pressbuttonSmall = BlockSpecs.getImageFrom('assets/misc/pushbutton', 'svg');
BlockSpecs.caretrepeat = BlockSpecs.getImageFrom('assets/blocks/caretrepeat');
BlockSpecs.cmdS = BlockSpecs.getImageFrom('assets/blocks/shadowCmd', 'svg');
BlockSpecs.startS = BlockSpecs.getImageFrom('assets/blocks/shadowStart', 'svg');
BlockSpecs.endS = BlockSpecs.getImageFrom('assets/blocks/shadowEndShort', 'svg');
BlockSpecs.endLongS = BlockSpecs.getImageFrom('assets/blocks/shadowEndLong', 'svg');
BlockSpecs.repeatS = BlockSpecs.getImageFrom('assets/blocks/shadowRepeat');
}
static getImageFrom (url, ext) {
var img = document.createElement('img');
img.src = url + (ext ? '.' + ext : '.png');
if (!img.complete) {
loadassets[img.src] = img;
loadCount++;
img.onload = function () {
delete loadassets[img.src];
loadCount--;
};
}
return img;
}
static refreshLoading () {
for (var key in loadassets) {
if (loadassets[key].complete) {
loadCount--;
}
}
}
};
BlockSpecs.setupCategories = function () {
return new Array(
[
BlockSpecs.getImageFrom('assets/categories/StartOn', 'svg'),
BlockSpecs.getImageFrom('assets/categories/StartOff', 'svg'),
Settings.categoryStartColor
],
[
BlockSpecs.getImageFrom('assets/categories/MotionOn', 'svg'),
BlockSpecs.getImageFrom('assets/categories/MotionOff', 'svg'),
Settings.categoryMotionColor
],
[
BlockSpecs.getImageFrom('assets/categories/LooksOn', 'svg'),
BlockSpecs.getImageFrom('assets/categories/LooksOff', 'svg'),
Settings.categoryLooksColor
],
[
BlockSpecs.getImageFrom('assets/categories/SoundOn', 'svg'),
BlockSpecs.getImageFrom('assets/categories/SoundOff', 'svg'),
Settings.categorySoundColor
],
[
BlockSpecs.getImageFrom('assets/categories/FlowOn', 'svg'),
BlockSpecs.getImageFrom('assets/categories/FlowOff', 'svg'),
Settings.categoryFlowColor
],
[
BlockSpecs.getImageFrom('assets/categories/StopOn', 'svg'),
BlockSpecs.getImageFrom('assets/categories/StopOff', 'svg'),
Settings.categoryStopColor
]
);
};
static setupCategories () {
return new Array(
[
BlockSpecs.getImageFrom('assets/categories/StartOn', 'svg'),
BlockSpecs.getImageFrom('assets/categories/StartOff', 'svg'),
Settings.categoryStartColor
],
[
BlockSpecs.getImageFrom('assets/categories/MotionOn', 'svg'),
BlockSpecs.getImageFrom('assets/categories/MotionOff', 'svg'),
Settings.categoryMotionColor
],
[
BlockSpecs.getImageFrom('assets/categories/LooksOn', 'svg'),
BlockSpecs.getImageFrom('assets/categories/LooksOff', 'svg'),
Settings.categoryLooksColor
],
[
BlockSpecs.getImageFrom('assets/categories/SoundOn', 'svg'),
BlockSpecs.getImageFrom('assets/categories/SoundOff', 'svg'),
Settings.categorySoundColor
],
[
BlockSpecs.getImageFrom('assets/categories/FlowOn', 'svg'),
BlockSpecs.getImageFrom('assets/categories/FlowOff', 'svg'),
Settings.categoryFlowColor
],
[
BlockSpecs.getImageFrom('assets/categories/StopOn', 'svg'),
BlockSpecs.getImageFrom('assets/categories/StopOff', 'svg'),
Settings.categoryStopColor
]
);
}
BlockSpecs.setupPalettesDef = function () {
return [['onflag', 'onclick', 'ontouch', 'onmessage', 'message'],
['forward', 'back', 'up', 'down', 'right', 'left', 'hop', 'home'],
['say', 'space', 'grow', 'shrink', 'same', 'space', 'hide', 'show'],
[],
['wait', 'stopmine', 'setspeed', 'repeat'],
['endstack', 'forever']];
};
static setupPalettesDef () {
return [['onflag', 'onclick', 'ontouch', 'onmessage', 'message'],
['forward', 'back', 'up', 'down', 'right', 'left', 'hop', 'home'],
['say', 'space', 'grow', 'shrink', 'same', 'space', 'hide', 'show'],
[],
['wait', 'stopmine', 'setspeed', 'repeat'],
['endstack', 'forever']];
}
///////////////////////////////
// Data Structure
//
// name - blocktype, icon or datastructure, blockshape, argtype, initial value, highlight, min, max, shadow
//
// arg types:
// null
// n -> number field;
// t -> text field
// m --> image menu with argvalue equal to name;
// d --> image menu with argvalue equal to number;
// c -- > color drop down
// s --> sound name
// p --> page icon
//
////////////////////////////////
///////////////////////////////
// Data Structure
//
// name - blocktype, icon or datastructure, blockshape, argtype, initial value, highlight, min, max, shadow
//
// arg types:
// null
// n -> number field;
// t -> text field
// m --> image menu with argvalue equal to name;
// d --> image menu with argvalue equal to number;
// c -- > color drop down
// s --> sound name
// p --> page icon
//
////////////////////////////////
BlockSpecs.setupBlocksSpecs = function () {
return {
'onflag': ['onflag', BlockSpecs.getImageFrom('assets/blockicons/greenFlag', 'svg'),
BlockSpecs.yellowStart, null, null, BlockSpecs.yellowStartH, null, null, BlockSpecs.startS],
'onmessage': ['onmessage', BlockSpecs.getshapes, BlockSpecs.yellowStart, 'm', 'Orange',
BlockSpecs.yellowStartH, null, null, BlockSpecs.startS],
'onclick': ['onclick', BlockSpecs.getImageFrom('assets/blockicons/OnTouch', 'svg'),
BlockSpecs.yellowStart, null, null, BlockSpecs.yellowStartH, null, null, BlockSpecs.startS],
'ontouch': ['ontouch', BlockSpecs.getImageFrom('assets/blockicons/Bump', 'svg'),
BlockSpecs.yellowStart, null, null, BlockSpecs.yellowStartH, null, null, BlockSpecs.startS],
'message': ['message', BlockSpecs.sendshapes, BlockSpecs.yellowCmd, 'm', 'Orange',
BlockSpecs.yellowCmdH, null, null, BlockSpecs.cmdS],
static setupBlocksSpecs () {
return {
'onflag': ['onflag', BlockSpecs.getImageFrom('assets/blockicons/greenFlag', 'svg'),
BlockSpecs.yellowStart, null, null, BlockSpecs.yellowStartH, null, null, BlockSpecs.startS],
'onmessage': ['onmessage', getshapes, BlockSpecs.yellowStart, 'm', 'Orange',
BlockSpecs.yellowStartH, null, null, BlockSpecs.startS],
'onclick': ['onclick', BlockSpecs.getImageFrom('assets/blockicons/OnTouch', 'svg'),
BlockSpecs.yellowStart, null, null, BlockSpecs.yellowStartH, null, null, BlockSpecs.startS],
'ontouch': ['ontouch', BlockSpecs.getImageFrom('assets/blockicons/Bump', 'svg'),
BlockSpecs.yellowStart, null, null, BlockSpecs.yellowStartH, null, null, BlockSpecs.startS],
'message': ['message', sendshapes, BlockSpecs.yellowCmd, 'm', 'Orange',
BlockSpecs.yellowCmdH, null, null, BlockSpecs.cmdS],
'repeat': ['repeat', BlockSpecs.getImageFrom('assets/blockicons/Repeat', 'svg'),
BlockSpecs.cShape, 'n', 4, BlockSpecs.cShapeH, 0, 24, BlockSpecs.repeatS],
'repeat': ['repeat', BlockSpecs.getImageFrom('assets/blockicons/Repeat', 'svg'),
BlockSpecs.cShape, 'n', 4, BlockSpecs.cShapeH, 0, 24, BlockSpecs.repeatS],
'forward': ['forward', BlockSpecs.getImageFrom('assets/blockicons/Foward', 'svg'),
BlockSpecs.blueCmd, 'n', 1, BlockSpecs.blueCmdH, -20, 20, BlockSpecs.cmdS],
'back': ['back', BlockSpecs.getImageFrom('assets/blockicons/Back', 'svg'),
BlockSpecs.blueCmd, 'n', 1, BlockSpecs.blueCmdH, -20, 20, BlockSpecs.cmdS],
'up': ['up', BlockSpecs.getImageFrom('assets/blockicons/Up', 'svg'),
BlockSpecs.blueCmd, 'n', 1, BlockSpecs.blueCmdH, -15, 15, BlockSpecs.cmdS],
'down': ['down', BlockSpecs.getImageFrom('assets/blockicons/Down', 'svg'),
BlockSpecs.blueCmd, 'n', 1, BlockSpecs.blueCmdH, -15, 15, BlockSpecs.cmdS],
'right': ['right', BlockSpecs.getImageFrom('assets/blockicons/Right', 'svg'),
BlockSpecs.blueCmd, 'n', 1, BlockSpecs.blueCmdH, -12, 12, BlockSpecs.cmdS],
'left': ['left', BlockSpecs.getImageFrom('assets/blockicons/Left', 'svg'),
BlockSpecs.blueCmd, 'n', 1, BlockSpecs.blueCmdH, -12, 12, BlockSpecs.cmdS],
'home': ['home', BlockSpecs.getImageFrom('assets/blockicons/Home', 'svg'),
BlockSpecs.blueCmd, null, null, BlockSpecs.blueCmdH, null, null, BlockSpecs.cmdS],
'hop': ['hop', BlockSpecs.getImageFrom('assets/blockicons/Hop', 'svg'),
BlockSpecs.blueCmd, 'n', 2, BlockSpecs.blueCmdH, -15, 15, BlockSpecs.cmdS],
'forward': ['forward', BlockSpecs.getImageFrom('assets/blockicons/Foward', 'svg'),
BlockSpecs.blueCmd, 'n', 1, BlockSpecs.blueCmdH, -20, 20, BlockSpecs.cmdS],
'back': ['back', BlockSpecs.getImageFrom('assets/blockicons/Back', 'svg'),
BlockSpecs.blueCmd, 'n', 1, BlockSpecs.blueCmdH, -20, 20, BlockSpecs.cmdS],
'up': ['up', BlockSpecs.getImageFrom('assets/blockicons/Up', 'svg'),
BlockSpecs.blueCmd, 'n', 1, BlockSpecs.blueCmdH, -15, 15, BlockSpecs.cmdS],
'down': ['down', BlockSpecs.getImageFrom('assets/blockicons/Down', 'svg'),
BlockSpecs.blueCmd, 'n', 1, BlockSpecs.blueCmdH, -15, 15, BlockSpecs.cmdS],
'right': ['right', BlockSpecs.getImageFrom('assets/blockicons/Right', 'svg'),
BlockSpecs.blueCmd, 'n', 1, BlockSpecs.blueCmdH, -12, 12, BlockSpecs.cmdS],
'left': ['left', BlockSpecs.getImageFrom('assets/blockicons/Left', 'svg'),
BlockSpecs.blueCmd, 'n', 1, BlockSpecs.blueCmdH, -12, 12, BlockSpecs.cmdS],
'home': ['home', BlockSpecs.getImageFrom('assets/blockicons/Home', 'svg'),
BlockSpecs.blueCmd, null, null, BlockSpecs.blueCmdH, null, null, BlockSpecs.cmdS],
'hop': ['hop', BlockSpecs.getImageFrom('assets/blockicons/Hop', 'svg'),
BlockSpecs.blueCmd, 'n', 2, BlockSpecs.blueCmdH, -15, 15, BlockSpecs.cmdS],
'wait': ['wait', BlockSpecs.getImageFrom('assets/blockicons/Wait', 'svg'),
BlockSpecs.orangeCmd, 'n', 10, BlockSpecs.orangeCmdH, 0, 50, BlockSpecs.cmdS],
'setspeed': ['setspeed', BlockSpecs.speeds, BlockSpecs.orangeCmd, 'd', 1,
BlockSpecs.orangeCmdH, null, null, BlockSpecs.cmdS],
'stopmine': ['stopmine', BlockSpecs.getImageFrom('assets/blockicons/Stop', 'svg'),
BlockSpecs.orangeCmd, null, null, BlockSpecs.orangeCmdH, null, null, BlockSpecs.cmdS],
'wait': ['wait', BlockSpecs.getImageFrom('assets/blockicons/Wait', 'svg'),
BlockSpecs.orangeCmd, 'n', 10, BlockSpecs.orangeCmdH, 0, 50, BlockSpecs.cmdS],
'setspeed': ['setspeed', speeds, BlockSpecs.orangeCmd, 'd', 1,
BlockSpecs.orangeCmdH, null, null, BlockSpecs.cmdS],
'stopmine': ['stopmine', BlockSpecs.getImageFrom('assets/blockicons/Stop', 'svg'),
BlockSpecs.orangeCmd, null, null, BlockSpecs.orangeCmdH, null, null, BlockSpecs.cmdS],
'say': ['say', BlockSpecs.getImageFrom('assets/blockicons/Say', 'svg'),
BlockSpecs.pinkCmd, 't',
Localization.localize('SAY_BLOCK_DEFAULT_ARGUMENT'), BlockSpecs.pinkCmdH, null, null, BlockSpecs.cmdS],
'show': ['show', BlockSpecs.getImageFrom('assets/blockicons/Appear', 'svg'),
BlockSpecs.pinkCmd, null, null, BlockSpecs.pinkCmdH, null, null, BlockSpecs.cmdS],
'hide': ['hide', BlockSpecs.getImageFrom('assets/blockicons/Disappear', 'svg'),
BlockSpecs.pinkCmd, null, null, BlockSpecs.pinkCmdH, null, null, BlockSpecs.cmdS],
'grow': ['grow', BlockSpecs.getImageFrom('assets/blockicons/Grow', 'svg'),
BlockSpecs.pinkCmd, 'n', 2, BlockSpecs.pinkCmdH, -10, 10, BlockSpecs.cmdS],
'shrink': ['shrink', BlockSpecs.getImageFrom('assets/blockicons/Shrink', 'svg'),
BlockSpecs.pinkCmd, 'n', 2, BlockSpecs.pinkCmdH, -10, 10, BlockSpecs.cmdS],
'same': ['same', BlockSpecs.getImageFrom('assets/blockicons/Reset', 'svg'),
BlockSpecs.pinkCmd, null, null, BlockSpecs.pinkCmdH, null, null, BlockSpecs.cmdS],
'say': ['say', BlockSpecs.getImageFrom('assets/blockicons/Say', 'svg'),
BlockSpecs.pinkCmd, 't',
Localization.localize('SAY_BLOCK_DEFAULT_ARGUMENT'), BlockSpecs.pinkCmdH, null, null, BlockSpecs.cmdS],
'show': ['show', BlockSpecs.getImageFrom('assets/blockicons/Appear', 'svg'),
BlockSpecs.pinkCmd, null, null, BlockSpecs.pinkCmdH, null, null, BlockSpecs.cmdS],
'hide': ['hide', BlockSpecs.getImageFrom('assets/blockicons/Disappear', 'svg'),
BlockSpecs.pinkCmd, null, null, BlockSpecs.pinkCmdH, null, null, BlockSpecs.cmdS],
'grow': ['grow', BlockSpecs.getImageFrom('assets/blockicons/Grow', 'svg'),
BlockSpecs.pinkCmd, 'n', 2, BlockSpecs.pinkCmdH, -10, 10, BlockSpecs.cmdS],
'shrink': ['shrink', BlockSpecs.getImageFrom('assets/blockicons/Shrink', 'svg'),
BlockSpecs.pinkCmd, 'n', 2, BlockSpecs.pinkCmdH, -10, 10, BlockSpecs.cmdS],
'same': ['same', BlockSpecs.getImageFrom('assets/blockicons/Reset', 'svg'),
BlockSpecs.pinkCmd, null, null, BlockSpecs.pinkCmdH, null, null, BlockSpecs.cmdS],
'playsnd': ['playsnd', BlockSpecs.getImageFrom('assets/blockicons/Speaker', 'svg'),
BlockSpecs.limeCmd, 's', 'pop.mp3', BlockSpecs.limeCmdH, null, null, BlockSpecs.cmdS],
'playusersnd': ['playusersnd', BlockSpecs.getImageFrom('assets/blockicons/Microphone', 'svg'),
BlockSpecs.limeCmd, 'r', '1', BlockSpecs.limeCmdH, null, null, BlockSpecs.cmdS],
'endstack': ['endstack', null, BlockSpecs.redEnd, null, null, BlockSpecs.redEndH, null, null, BlockSpecs.endS],
'forever': ['forever', BlockSpecs.getImageFrom('assets/blockicons/Forever', 'svg'),
BlockSpecs.redEnd, null, null, BlockSpecs.redEndH, null, null, BlockSpecs.endS],
'gotopage': ['gotopage', null,
BlockSpecs.redEndLong, 'p', '2', BlockSpecs.redEndLongH, null, null, BlockSpecs.endLongS],
'caretstart': ['caretstart', null,
BlockSpecs.getImageFrom('assets/blocks/caretstart', 'svg'), null, null, null, null, null],
'caretend': ['caretend', null,
BlockSpecs.getImageFrom('assets/blocks/caretend', 'svg'), null, null, null, null, null],
'caretrepeat': ['caretrepeat', null,
BlockSpecs.getImageFrom('assets/blocks/caretrepeat'), null, null, null, null, null],
'caretcmd': ['caretcmd', null,
BlockSpecs.getImageFrom('assets/blocks/caretcmd', 'svg'), null, null, null, null, null]
'playsnd': ['playsnd', BlockSpecs.getImageFrom('assets/blockicons/Speaker', 'svg'),
BlockSpecs.limeCmd, 's', 'pop.mp3', BlockSpecs.limeCmdH, null, null, BlockSpecs.cmdS],
'playusersnd': ['playusersnd', BlockSpecs.getImageFrom('assets/blockicons/Microphone', 'svg'),
BlockSpecs.limeCmd, 'r', '1', BlockSpecs.limeCmdH, null, null, BlockSpecs.cmdS],
'endstack': ['endstack', null, BlockSpecs.redEnd, null, null,
BlockSpecs.redEndH, null, null, BlockSpecs.endS],
'forever': ['forever', BlockSpecs.getImageFrom('assets/blockicons/Forever', 'svg'),
BlockSpecs.redEnd, null, null, BlockSpecs.redEndH, null, null, BlockSpecs.endS],
'gotopage': ['gotopage', null,
BlockSpecs.redEndLong, 'p', '2', BlockSpecs.redEndLongH, null, null, BlockSpecs.endLongS],
'caretstart': ['caretstart', null,
BlockSpecs.getImageFrom('assets/blocks/caretstart', 'svg'), null, null, null, null, null],
'caretend': ['caretend', null,
BlockSpecs.getImageFrom('assets/blocks/caretend', 'svg'), null, null, null, null, null],
'caretrepeat': ['caretrepeat', null,
BlockSpecs.getImageFrom('assets/blocks/caretrepeat'), null, null, null, null, null],
'caretcmd': ['caretcmd', null,
BlockSpecs.getImageFrom('assets/blocks/caretcmd', 'svg'), null, null, null, null, null]
};
};
};
}
BlockSpecs.blockDesc = function (b, spr) {
var str = b.getArgValue() ? b.getArgValue().toString() : (b.blocktype == 'playsnd') ? 'SOUND' : '';
static blockDesc (b, spr) {
var str = b.getArgValue() ? b.getArgValue().toString() : (b.blocktype == 'playsnd') ? 'SOUND' : '';
return {
'onflag': Localization.localize('BLOCK_DESC_GREEN_FLAG'),
'onclick': Localization.localize('BLOCK_DESC_ON_TAP', {
CHARACTER_NAME: spr.name
}),
'ontouch': Localization.localize('BLOCK_DESC_ON_BUMP', {
CHARACTER_NAME: spr.name ? spr.name : ''
}),
'onmessage': Localization.localize('BLOCK_DESC_ON_MESSAGE', {
COLOR: Localization.localize('BLOCK_DESC_MESSAGE_COLOR_ORANGE')
}),
'repeat': Localization.localize('BLOCK_DESC_REPEAT'),
'forward': Localization.localize('BLOCK_DESC_MOVE_RIGHT'),
'back': Localization.localize('BLOCK_DESC_MOVE_LEFT'),
'up': Localization.localize('BLOCK_DESC_MOVE_UP'),
'down': Localization.localize('BLOCK_DESC_MOVE_DOWN'),
'home': Localization.localize('BLOCK_DESC_GO_HOME'),
'left': Localization.localize('BLOCK_DESC_TURN_LEFT'),
'right': Localization.localize('BLOCK_DESC_TURN_RIGHT'),
'hop': Localization.localize('BLOCK_DESC_HOP'),
'wait': Localization.localize('BLOCK_DESC_WAIT'),
'setspeed': Localization.localize('BLOCK_DESC_SET_SPEED'),
'stopmine': Localization.localize('BLOCK_DESC_STOP', {
CHARACTER_NAME: spr.name ? spr.name : spr.str
}),
'say': Localization.localize('BLOCK_DESC_SAY'),
'show': Localization.localize('BLOCK_DESC_SHOW'),
'hide': Localization.localize('BLOCK_DESC_HIDE'),
'grow': Localization.localize('BLOCK_DESC_GROW'),
'shrink': Localization.localize('BLOCK_DESC_SHRINK'),
'same': Localization.localize('BLOCK_DESC_RESET_SIZE'),
'playsnd': Localization.localize('BLOCK_DESC_PLAY_SOUND', {
SOUND_NAME: Localization.localize('BLOCK_DESC_PLAY_SOUND_POP')
}),
'playusersnd': Localization.localize('BLOCK_DESC_PLAY_RECORDED_SOUND'),
'endstack': Localization.localize('BLOCK_DESC_END'),
'stopall': Localization.localize('BLOCK_DESC_STOP', {
CHARACTER_NAME: spr.name ? spr.name : ''
}),
'forever': Localization.localize('BLOCK_DESC_REPEAT_FOREVER'),
'gotopage': Localization.localize('BLOCK_DESC_GO_TO_PAGE', {
PAGE: str
}),
'message': Localization.localize('BLOCK_DESC_SEND_MESSAGE', {
COLOR: Localization.localize('BLOCK_DESC_MESSAGE_COLOR_ORANGE')
})
};
};
return {
'onflag': Localization.localize('BLOCK_DESC_GREEN_FLAG'),
'onclick': Localization.localize('BLOCK_DESC_ON_TAP', {
CHARACTER_NAME: spr.name
}),
'ontouch': Localization.localize('BLOCK_DESC_ON_BUMP', {
CHARACTER_NAME: spr.name ? spr.name : ''
}),
'onmessage': Localization.localize('BLOCK_DESC_ON_MESSAGE', {
COLOR: Localization.localize('BLOCK_DESC_MESSAGE_COLOR_ORANGE')
}),
'repeat': Localization.localize('BLOCK_DESC_REPEAT'),
'forward': Localization.localize('BLOCK_DESC_MOVE_RIGHT'),
'back': Localization.localize('BLOCK_DESC_MOVE_LEFT'),
'up': Localization.localize('BLOCK_DESC_MOVE_UP'),
'down': Localization.localize('BLOCK_DESC_MOVE_DOWN'),
'home': Localization.localize('BLOCK_DESC_GO_HOME'),
'left': Localization.localize('BLOCK_DESC_TURN_LEFT'),
'right': Localization.localize('BLOCK_DESC_TURN_RIGHT'),
'hop': Localization.localize('BLOCK_DESC_HOP'),
'wait': Localization.localize('BLOCK_DESC_WAIT'),
'setspeed': Localization.localize('BLOCK_DESC_SET_SPEED'),
'stopmine': Localization.localize('BLOCK_DESC_STOP', {
CHARACTER_NAME: spr.name ? spr.name : spr.str
}),
'say': Localization.localize('BLOCK_DESC_SAY'),
'show': Localization.localize('BLOCK_DESC_SHOW'),
'hide': Localization.localize('BLOCK_DESC_HIDE'),
'grow': Localization.localize('BLOCK_DESC_GROW'),
'shrink': Localization.localize('BLOCK_DESC_SHRINK'),
'same': Localization.localize('BLOCK_DESC_RESET_SIZE'),
'playsnd': Localization.localize('BLOCK_DESC_PLAY_SOUND', {
SOUND_NAME: Localization.localize('BLOCK_DESC_PLAY_SOUND_POP')
}),
'playusersnd': Localization.localize('BLOCK_DESC_PLAY_RECORDED_SOUND'),
'endstack': Localization.localize('BLOCK_DESC_END'),
'stopall': Localization.localize('BLOCK_DESC_STOP', {
CHARACTER_NAME: spr.name ? spr.name : ''
}),
'forever': Localization.localize('BLOCK_DESC_REPEAT_FOREVER'),
'gotopage': Localization.localize('BLOCK_DESC_GO_TO_PAGE', {
PAGE: str
}),
'message': Localization.localize('BLOCK_DESC_SEND_MESSAGE', {
COLOR: Localization.localize('BLOCK_DESC_MESSAGE_COLOR_ORANGE')
})
};
}
}

View file

@ -1,92 +1,104 @@
var Menu = function () {};
import BlockSpecs from './BlockSpecs';
import {scaleMultiplier, setProps, setCanvasSize, newHTML, isTablet,
newDiv, getDocumentHeight, drawThumbnail, frame, globalx, globaly} from '../../utils/lib';
Menu.openMenu = undefined;
let openMenu = undefined;
Menu.openDropDown = function (b, fcn) {
var size = 50;
var color = b.owner.blocktype == 'setspeed' ? 'orange' : 'yellow';
var list = JSON.parse(b.owner.arg.list);
var num = b.owner.arg.numperrow;
var p = b.parentNode;
var dh = size * Math.round(list.length / num);
var rows = list.length / num;
var w = size * list.length / rows;
var scaledWidth = w * scaleMultiplier;
var dx = b.left + (b.offsetWidth - scaledWidth) / 2;
if ((dx + scaledWidth) > p.width) {
dx -= ((dx + scaledWidth) - p.width);
export default class Menu {
static get openMenu () {
return openMenu;
}
if (dx < 5) {
dx = 5;
}
dx += globalx(p, 0);
var dy = b.top + b.offsetHeight - ((10 + 18) * scaleMultiplier) + globaly(p, 0);
if ((dy + ((10 + dh) * scaleMultiplier)) > getDocumentHeight()) {
dy = getDocumentHeight() - ((15 + dh) * scaleMultiplier);
}
var mu = newDiv(frame, dx, dy, w, dh, {
position: 'absolute',
zIndex: 100000,
webkitTransform: 'translate(' + (-w / 2) + 'px,' + (-dh / 2) + 'px) ' +
'scale(' + scaleMultiplier + ', ' + scaleMultiplier + ') ' +
'translate(' + (w / 2) + 'px, ' + (dh / 2) + 'px)'
});
mu.setAttribute('class', 'menustyle ' + color);
mu.active = b;
for (var i = 0; i < list.length; i++) {
Menu.addImageToDropDown(mu, list[i], b, fcn);
}
Menu.openMenu = mu;
};
Menu.addImageToDropDown = function (mu, c, block, fcn) {
var img = BlockSpecs.getImageFrom('assets/blockicons/' + c, 'svg');
var cs = newHTML('div', 'ddchoice', mu);
var micon = newHTML('canvas', undefined, cs);
var iconSize = 42;
var scaledIconSize = iconSize * window.devicePixelRatio;
setCanvasSize(micon, scaledIconSize, scaledIconSize);
setProps(micon.style, {
webkitTransform: 'translate(' + (-scaledIconSize / 2) + 'px, ' + (-scaledIconSize / 2) + 'px) ' +
'scale(' + (1 / window.devicePixelRatio) + ', ' + (1 / window.devicePixelRatio) + ') ' +
'translate(' + (scaledIconSize / 2) + 'px, ' + (scaledIconSize / 2) + 'px)'
});
if (!img.complete) {
img.onload = function () {
static set openMenu (newOpenMenu) {
openMenu = newOpenMenu;
}
static openDropDown (b, fcn) {
var size = 50;
var color = b.owner.blocktype == 'setspeed' ? 'orange' : 'yellow';
var list = JSON.parse(b.owner.arg.list);
var num = b.owner.arg.numperrow;
var p = b.parentNode;
var dh = size * Math.round(list.length / num);
var rows = list.length / num;
var w = size * list.length / rows;
var scaledWidth = w * scaleMultiplier;
var dx = b.left + (b.offsetWidth - scaledWidth) / 2;
if ((dx + scaledWidth) > p.width) {
dx -= ((dx + scaledWidth) - p.width);
}
if (dx < 5) {
dx = 5;
}
dx += globalx(p, 0);
var dy = b.top + b.offsetHeight - ((10 + 18) * scaleMultiplier) + globaly(p, 0);
if ((dy + ((10 + dh) * scaleMultiplier)) > getDocumentHeight()) {
dy = getDocumentHeight() - ((15 + dh) * scaleMultiplier);
}
var mu = newDiv(frame, dx, dy, w, dh, {
position: 'absolute',
zIndex: 100000,
webkitTransform: 'translate(' + (-w / 2) + 'px,' + (-dh / 2) + 'px) ' +
'scale(' + scaleMultiplier + ', ' + scaleMultiplier + ') ' +
'translate(' + (w / 2) + 'px, ' + (dh / 2) + 'px)'
});
mu.setAttribute('class', 'menustyle ' + color);
mu.active = b;
for (var i = 0; i < list.length; i++) {
Menu.addImageToDropDown(mu, list[i], b, fcn);
}
openMenu = mu;
}
static addImageToDropDown (mu, c, block, fcn) {
var img = BlockSpecs.getImageFrom('assets/blockicons/' + c, 'svg');
var cs = newHTML('div', 'ddchoice', mu);
var micon = newHTML('canvas', undefined, cs);
var iconSize = 42;
var scaledIconSize = iconSize * window.devicePixelRatio;
setCanvasSize(micon, scaledIconSize, scaledIconSize);
setProps(micon.style, {
webkitTransform: 'translate(' + (-scaledIconSize / 2) + 'px, ' + (-scaledIconSize / 2) + 'px) ' +
'scale(' + (1 / window.devicePixelRatio) + ', ' + (1 / window.devicePixelRatio) + ') ' +
'translate(' + (scaledIconSize / 2) + 'px, ' + (scaledIconSize / 2) + 'px)'
});
if (!img.complete) {
img.onload = function () {
drawThumbnail(img, micon);
};
} else {
drawThumbnail(img, micon);
};
} else {
drawThumbnail(img, micon);
}
if (isTablet) {
cs.ontouchstart = function (evt) {
handleTouchStart(evt);
};
} else {
cs.onmouseover = function (evt) {
Menu.highlightdot(evt);
};
cs.onmouseout = function (evt) {
Menu.unhighlightdot(evt);
};
cs.onmousedown = function (evt) {
fcn(evt, mu, block, c);
};
}
function handleTouchStart (e) {
if (isTablet && e.touches && (e.touches.length > 1)) {
return;
}
e.preventDefault();
e.stopPropagation();
fcn(e, mu, block, c);
}
}
if (isTablet) {
cs.ontouchstart = function (evt) {
handleTouchStart(evt);
};
} else {
cs.onmouseover = function (evt) {
Menu.highlightdot(evt);
};
cs.onmouseout = function (evt) {
Menu.unhighlightdot(evt);
};
cs.onmousedown = function (evt) {
fcn(evt, mu, block, c);
};
}
function handleTouchStart (e) {
if (isTablet && e.touches && (e.touches.length > 1)) {
static closeMyOpenMenu () {
if (!openMenu) {
return;
}
e.preventDefault();
e.stopPropagation();
fcn(e, mu, block, c);
openMenu.parentNode.removeChild(openMenu);
openMenu = undefined;
}
};
Menu.closeMyOpenMenu = function () {
if (!Menu.openMenu) {
return;
}
Menu.openMenu.parentNode.removeChild(Menu.openMenu);
Menu.openMenu = undefined;
};
}

File diff suppressed because it is too large Load diff

View file

@ -863,7 +863,6 @@ Sprite.prototype.activateInput = function () {
var ti = document.forms.activetextbox.typing;
gn('textbox').style.visibility = 'visible';
var me = this;
Undo.aux = Project.getProject(ScratchJr.stage.currentPage.id);
ti.onblur = function () {
me.unfocusText();
};

View file

@ -1,66 +1,74 @@
var Alert = function () {};
import DrawPath from '../../utils/DrawPath';
import {globalx, globaly, scaleMultiplier, newCanvas,
setCanvasSize, setProps, writeText, getStringSize} from '../../utils/lib';
Alert.balloon = undefined;
let balloon = undefined;
Alert.close = function () {
if (!Alert.balloon) {
return;
}
Alert.balloon.parentNode.removeChild(Alert.balloon);
Alert.balloon = undefined;
};
Alert.open = function (p, obj, label, color) {
if (Alert.balloon) {
Alert.close();
}
var scale = scaleMultiplier;
var w = 80;
var h = 24;
var dx = (globalx(obj, obj.offsetLeft) + (obj.offsetWidth / 2)) - (w + 7 * 2 + 4) * scale / 2;
var dy = globaly(obj, obj.offsetTop) - (24 * scale);
if (dy < 5 * scale) {
dy = 5 * scale;
export default class Alert {
static get balloon () {
return balloon;
}
Alert.balloon = newCanvas(p, dx, dy, w, h, {
position: 'absolute',
zIndex: 2
});
Alert.balloon.icon = obj;
var ctx = Alert.balloon.getContext('2d');
w = 16 + getStringSize(ctx, 'bold 14px Verdana', label).width;
if (w < 36) {
w = 36;
static close () {
if (!balloon) {
return;
}
balloon.parentNode.removeChild(balloon);
balloon = undefined;
}
dx = (globalx(obj, obj.offsetLeft) + (obj.offsetWidth / 2)) - (w + 7 * 2 + 4) * scale / 2;
if (dx < 5 * scale) {
dx = 5 * scale;
}
dx = Math.floor(dx);
setCanvasSize(Alert.balloon, w, 36);
setProps(Alert.balloon.style, {
position: 'absolute',
left: dx + 'px',
zIndex: 1000,
webkitTransform: 'translate(' + (-w / 2) + 'px, ' + (-h / 2) + 'px) ' +
'scale(' + scale + ', ' + scale + ') ' +
'translate(' + (w / 2) + 'px, ' + (h / 2) + 'px) '
});
Alert.draw(Alert.balloon.getContext('2d'), 6, w, h, color);
writeText(ctx, 'bold 14px Verdana', 'white', label, 20, 8);
};
Alert.draw = function (ctx, curve, w, h, color) {
curve = 10;
var path = new Array(['M', 0, curve], ['q', 0, -curve, curve, -curve], ['h', w - curve * 2],
['q', curve, 0, curve, curve], ['v', h - curve * 2], ['q', 0, curve, -curve, curve],
['h', -(w / 2) + 7 + curve], ['l', -7, 7], ['l', -7, -7], ['h', -(w / 2) + 7 + curve],
['q', -curve, 0, -curve, -curve], ['Z']
);
ctx.clearRect(0, 0, Math.max(ctx.canvas.width, w), Math.max(ctx.canvas.height, h));
ctx.fillStyle = color;
ctx.beginPath();
DrawPath.render(ctx, path);
ctx.fill();
};
static open (p, obj, label, color) {
if (balloon) {
Alert.close();
}
var scale = scaleMultiplier;
var w = 80;
var h = 24;
var dx = (globalx(obj, obj.offsetLeft) + (obj.offsetWidth / 2)) - (w + 7 * 2 + 4) * scale / 2;
var dy = globaly(obj, obj.offsetTop) - (24 * scale);
if (dy < 5 * scale) {
dy = 5 * scale;
}
balloon = newCanvas(p, dx, dy, w, h, {
position: 'absolute',
zIndex: 2
});
balloon.icon = obj;
var ctx = balloon.getContext('2d');
w = 16 + getStringSize(ctx, 'bold 14px Verdana', label).width;
if (w < 36) {
w = 36;
}
dx = (globalx(obj, obj.offsetLeft) + (obj.offsetWidth / 2)) - (w + 7 * 2 + 4) * scale / 2;
if (dx < 5 * scale) {
dx = 5 * scale;
}
dx = Math.floor(dx);
setCanvasSize(balloon, w, 36);
setProps(balloon.style, {
position: 'absolute',
left: dx + 'px',
zIndex: 1000,
webkitTransform: 'translate(' + (-w / 2) + 'px, ' + (-h / 2) + 'px) ' +
'scale(' + scale + ', ' + scale + ') ' +
'translate(' + (w / 2) + 'px, ' + (h / 2) + 'px) '
});
Alert.draw(balloon.getContext('2d'), 6, w, h, color);
writeText(ctx, 'bold 14px Verdana', 'white', label, 20, 8);
}
static draw (ctx, curve, w, h, color) {
curve = 10;
var path = new Array(['M', 0, curve], ['q', 0, -curve, curve, -curve], ['h', w - curve * 2],
['q', curve, 0, curve, curve], ['v', h - curve * 2], ['q', 0, curve, -curve, curve],
['h', -(w / 2) + 7 + curve], ['l', -7, 7], ['l', -7, -7], ['h', -(w / 2) + 7 + curve],
['q', -curve, 0, -curve, -curve], ['Z']
);
ctx.clearRect(0, 0, Math.max(ctx.canvas.width, w), Math.max(ctx.canvas.height, h));
ctx.fillStyle = color;
ctx.beginPath();
DrawPath.render(ctx, path);
ctx.fill();
}
}

View file

@ -2,264 +2,276 @@
// Stage grid
//////////////////////////////
var Grid = function () {};
import ScratchJr from '../ScratchJr';
import Events from '../../utils/Events';
import Localization from '../../utils/Localization';
import {gn, scaleMultiplier, isTablet, newDiv, setProps, newP, newCanvas} from '../../utils/lib';
Grid.width = 482;
Grid.height = 362;
Grid.size = 24;
let width = 482;
let height = 362;
let size = 24;
let hidden = true;
Grid.hidden = true;
Grid.init = function (div) {
var w = div.offsetWidth;
var h = div.offsetHeight;
var grid = newDiv(div, 0, 0, Grid.width, Grid.height, {
position: 'absolute',
zIndex: ScratchJr.layerTop
});
Grid.setScaleAndPosition(grid, scaleMultiplier, 47, 75, Grid.width, Grid.height);
grid.setAttribute('id', 'livegrid');
Grid.drawLines(grid, Grid.width, Grid.height);
Grid.createNumbering(w, h);
Grid.createCursor();
Grid.createYcursor();
Grid.createXcursor();
};
Grid.setScaleAndPosition = function (grid, scale, x, y, w, h) {
setProps(grid.style, {
webkitTransform: 'translate(' + (-w / 2) + 'px, ' + (-h / 2) + 'px) ' +
'scale(' + scale + ') ' +
'translate(' + (w / 2 + x) + 'px, ' + (h / 2 + y) + 'px)'
});
};
Grid.drawLines = function (grid, w, h) {
var cnv = newCanvas(grid, 0, 0, w, h, {
position: 'absolute'
});
cnv.style.opacity = 0.5;
var ctx = cnv.getContext('2d');
ctx.strokeStyle = '#B3B3B3';
ctx.lineWidth = 1;
var dx = Grid.size;
// vertical
for (var i = 0; i < 480 / Grid.size; i++) {
ctx.moveTo(dx, 0);
ctx.lineTo(dx, 360);
ctx.stroke();
dx += Grid.size;
export default class Grid {
static get size () {
return size;
}
var dy = Grid.size;
// horizontal
for (i = 0; i < 360 / Grid.size; i++) {
ctx.moveTo(0, dy);
ctx.lineTo(480, dy);
ctx.stroke();
dy += Grid.size;
}
if (isTablet) {
cnv.ontouchstart = function (evt) {
ScratchJr.stage.mouseDown(evt);
};
} else {
cnv.onmousedown = function (evt) {
ScratchJr.stage.mouseDown(evt);
};
}
};
Grid.createNumbering = function (w, h) {
var row = newDiv(gn('stageframe'), 0, 0, w - 46 - 30, 24, {
position: 'absolute',
zIndex: ScratchJr.layerTop
});
row.setAttribute('id', 'rownum');
Grid.setScaleAndPosition(row, scaleMultiplier, 46 - 24, 75 + Grid.height, w - 46 - 30, 24);
var offset = Grid.size;
var dx = offset;
for (var i = 0; i < 480 / offset; i++) {
var num = newDiv(row, dx, 0, Grid.size, Grid.size, {
static get hidden () {
return hidden;
}
static init (div) {
var w = div.offsetWidth;
var h = div.offsetHeight;
var grid = newDiv(div, 0, 0, width, height, {
position: 'absolute',
zIndex: 10
zIndex: ScratchJr.layerTop
});
var p = newP(num, Localization.localize('GRID_NUMBER', {
N: (i + 1)
}), {});
p.setAttribute('class', 'stylelabel');
dx += offset;
Grid.setScaleAndPosition(grid, scaleMultiplier, 47, 75, width, height);
grid.setAttribute('id', 'livegrid');
Grid.drawLines(grid, width, height);
Grid.createNumbering(w, h);
Grid.createCursor();
Grid.createYcursor();
Grid.createXcursor();
}
var column = newDiv(gn('stageframe'), 0, 0, 24, h + 24, {
position: 'absolute',
zIndex: ScratchJr.layerTop
});
column.setAttribute('id', 'colnum');
Grid.setScaleAndPosition(column, scaleMultiplier, 46 - 24, 74 + 1, 24, h + 24);
var dy = 360 - offset;
for (var j = 0; j < 360 / offset; j++) {
var numj = newDiv(column, 0, dy, Grid.size, Grid.size, {
static setScaleAndPosition (grid, scale, x, y, w, h) {
setProps(grid.style, {
webkitTransform: 'translate(' + (-w / 2) + 'px, ' + (-h / 2) + 'px) ' +
'scale(' + scale + ') ' +
'translate(' + (w / 2 + x) + 'px, ' + (h / 2 + y) + 'px)'
});
}
static drawLines (grid, w, h) {
var cnv = newCanvas(grid, 0, 0, w, h, {
position: 'absolute'
});
cnv.style.opacity = 0.5;
var ctx = cnv.getContext('2d');
ctx.strokeStyle = '#B3B3B3';
ctx.lineWidth = 1;
var dx = size;
// vertical
for (var i = 0; i < 480 / size; i++) {
ctx.moveTo(dx, 0);
ctx.lineTo(dx, 360);
ctx.stroke();
dx += size;
}
var dy = size;
// horizontal
for (i = 0; i < 360 / size; i++) {
ctx.moveTo(0, dy);
ctx.lineTo(480, dy);
ctx.stroke();
dy += size;
}
if (isTablet) {
cnv.ontouchstart = function (evt) {
ScratchJr.stage.mouseDown(evt);
};
} else {
cnv.onmousedown = function (evt) {
ScratchJr.stage.mouseDown(evt);
};
}
}
static createNumbering (w, h) {
var row = newDiv(gn('stageframe'), 0, 0, w - 46 - 30, 24, {
position: 'absolute',
zIndex: 10
zIndex: ScratchJr.layerTop
});
var py = newP(numj, Localization.localize('GRID_NUMBER', {
N: j + 1
}), {});
py.setAttribute('class', 'stylelabel');
dy -= offset;
}
};
Grid.createYcursor = function () {
var num = newDiv(gn('colnum'), 0, 0, Grid.size, Grid.size, {
position: 'absolute',
zIndex: 20
});
num.setAttribute('class', 'circle');
num.style.background = '#6a99c1';
num.setAttribute('id', 'ycursor');
var p = newP(num, 15, {});
p.setAttribute('class', 'circlenum');
};
Grid.createXcursor = function () {
var num = newDiv(gn('rownum'), Grid.size, 0, Grid.size, Grid.size, {
position: 'absolute',
zIndex: 20
});
num.setAttribute('class', 'circle');
num.style.background = '#6a99c1';
num.setAttribute('id', 'xcursor');
var p = newP(num, 1, {});
p.setAttribute('class', 'circlenum');
};
Grid.createCursor = function () {
var gc = newDiv(gn('livegrid'), 0, 0, Grid.size + 2, Grid.size + 2, {
position: 'absolute',
zIndex: ScratchJr.layerAboveBottom
});
gc.setAttribute('id', 'circlenum');
var cnv = newCanvas(gc, 0, 0, Grid.size + 2, Grid.size + 2, {
position: 'absolute'
});
if (isTablet) {
cnv.ontouchstart = function (evt) {
Grid.mouseDownOnCursor(evt);
};
} else {
cnv.onmousedown = function (evt) {
Grid.mouseDownOnCursor(evt);
};
}
var ctx = cnv.getContext('2d');
ctx.globalAlpha = 0.5;
ctx.fillStyle = '#28A5DA';
ctx.strokeStyle = '#656e73';
ctx.lineWidth = 3;
ctx.strokeRect(3, 3, Grid.size - 6, Grid.size - 6);
ctx.fillRect(3, 3, Grid.size - 6, Grid.size - 6);
if (isTablet) {
gc.ontouchstart = Grid.mouseDownOnCursor;
} else {
gc.onmousedown = Grid.mouseDownOnCursor;
}
};
Grid.mouseDownOnCursor = function (e) {
e.preventDefault();
e.stopPropagation();
var pt = ScratchJr.stage.getStagePt(e);
var spr = ScratchJr.getSprite();
ScratchJr.stage.initialPoint = {
x: pt.x,
y: pt.y
};
Events.dragthumbnail = spr.div;
Events.clearEvents();
if (!ScratchJr.inFullscreen && spr) {
Events.holdit(spr.div, ScratchJr.stage.startShaking);
}
ScratchJr.stage.setEvents();
};
Grid.updateCursor = function () {
if (Grid.hidden) {
return;
}
if (ScratchJr.inFullscreen) {
return;
}
if (!ScratchJr.stage.currentPage) {
return;
}
if (!ScratchJr.getSprite()) {
gn('circlenum').style.visibility = 'hidden';
gn('xcursor').style.visibility = 'hidden';
gn('ycursor').style.visibility = 'hidden';
return;
}
var spr = gn(ScratchJr.stage.currentPage.currentSpriteName);
if (!spr) {
return;
}
var obj = spr.owner;
var c = gn('circlenum');
if (!c) {
return;
}
var dx = obj.xcoor + Grid.size / 2;
var dy = obj.ycoor - Grid.size / 2;
gn('xcursor').style.visibility = 'visible';
gn('ycursor').style.visibility = 'visible';
gn('circlenum').style.visibility = 'visible';
Grid.setCursorsValues(dx, dy);
};
Grid.setCursorsValues = function (dx, dy) {
var c = gn('circlenum');
var numX = Math.round(dx / Grid.size);
var numY = Math.round(dy / Grid.size);
if (c.offsetLeft != (numX * 24)) {
var xc = gn('xcursor');
var xstate = ((numX < 1) || (numX > 20)) ? 'hidden' : 'visible';
setProps(xc.style, {
row.setAttribute('id', 'rownum');
Grid.setScaleAndPosition(row, scaleMultiplier, 46 - 24, 75 + height, w - 46 - 30, 24);
var offset = size;
var dx = offset;
for (var i = 0; i < 480 / offset; i++) {
var num = newDiv(row, dx, 0, size, size, {
position: 'absolute',
zIndex: 10
});
var p = newP(num, Localization.localize('GRID_NUMBER', {
N: (i + 1)
}), {});
p.setAttribute('class', 'stylelabel');
dx += offset;
}
var column = newDiv(gn('stageframe'), 0, 0, 24, h + 24, {
position: 'absolute',
left: (numX * 24) + 'px',
visibility: xstate
});
xc.childNodes[0].textContent = Localization.localize('GRID_NUMBER', {
N: numX
zIndex: ScratchJr.layerTop
});
column.setAttribute('id', 'colnum');
Grid.setScaleAndPosition(column, scaleMultiplier, 46 - 24, 74 + 1, 24, h + 24);
var dy = 360 - offset;
for (var j = 0; j < 360 / offset; j++) {
var numj = newDiv(column, 0, dy, size, size, {
position: 'absolute',
zIndex: 10
});
var py = newP(numj, Localization.localize('GRID_NUMBER', {
N: j + 1
}), {});
py.setAttribute('class', 'stylelabel');
dy -= offset;
}
}
if (c.offsetTop != (numY * 24)) {
var yc = gn('ycursor');
var ystate = ((numY < 0) || (numY > 14)) ? 'hidden' : 'visible';
setProps(yc.style, {
static createYcursor () {
var num = newDiv(gn('colnum'), 0, 0, size, size, {
position: 'absolute',
zIndex: 20
});
num.setAttribute('class', 'circle');
num.style.background = '#6a99c1';
num.setAttribute('id', 'ycursor');
var p = newP(num, 15, {});
p.setAttribute('class', 'circlenum');
}
static createXcursor () {
var num = newDiv(gn('rownum'), size, 0, size, size, {
position: 'absolute',
zIndex: 20
});
num.setAttribute('class', 'circle');
num.style.background = '#6a99c1';
num.setAttribute('id', 'xcursor');
var p = newP(num, 1, {});
p.setAttribute('class', 'circlenum');
}
static createCursor () {
var gc = newDiv(gn('livegrid'), 0, 0, size + 2, size + 2, {
position: 'absolute',
zIndex: ScratchJr.layerAboveBottom
});
gc.setAttribute('id', 'circlenum');
var cnv = newCanvas(gc, 0, 0, size + 2, size + 2, {
position: 'absolute'
});
if (isTablet) {
cnv.ontouchstart = function (evt) {
Grid.mouseDownOnCursor(evt);
};
} else {
cnv.onmousedown = function (evt) {
Grid.mouseDownOnCursor(evt);
};
}
var ctx = cnv.getContext('2d');
ctx.globalAlpha = 0.5;
ctx.fillStyle = '#28A5DA';
ctx.strokeStyle = '#656e73';
ctx.lineWidth = 3;
ctx.strokeRect(3, 3, size - 6, size - 6);
ctx.fillRect(3, 3, size - 6, size - 6);
if (isTablet) {
gc.ontouchstart = Grid.mouseDownOnCursor;
} else {
gc.onmousedown = Grid.mouseDownOnCursor;
}
}
static mouseDownOnCursor (e) {
e.preventDefault();
e.stopPropagation();
var pt = ScratchJr.stage.getStagePt(e);
var spr = ScratchJr.getSprite();
ScratchJr.stage.initialPoint = {
x: pt.x,
y: pt.y
};
Events.dragthumbnail = spr.div;
Events.clearEvents();
if (!ScratchJr.inFullscreen && spr) {
Events.holdit(spr.div, ScratchJr.stage.startShaking);
}
ScratchJr.stage.setEvents();
}
static updateCursor () {
if (hidden) {
return;
}
if (ScratchJr.inFullscreen) {
return;
}
if (!ScratchJr.stage.currentPage) {
return;
}
if (!ScratchJr.getSprite()) {
gn('circlenum').style.visibility = 'hidden';
gn('xcursor').style.visibility = 'hidden';
gn('ycursor').style.visibility = 'hidden';
return;
}
var spr = gn(ScratchJr.stage.currentPage.currentSpriteName);
if (!spr) {
return;
}
var obj = spr.owner;
var c = gn('circlenum');
if (!c) {
return;
}
var dx = obj.xcoor + size / 2;
var dy = obj.ycoor - size / 2;
gn('xcursor').style.visibility = 'visible';
gn('ycursor').style.visibility = 'visible';
gn('circlenum').style.visibility = 'visible';
Grid.setCursorsValues(dx, dy);
}
static setCursorsValues (dx, dy) {
var c = gn('circlenum');
var numX = Math.round(dx / size);
var numY = Math.round(dy / size);
if (c.offsetLeft != (numX * 24)) {
var xc = gn('xcursor');
var xstate = ((numX < 1) || (numX > 20)) ? 'hidden' : 'visible';
setProps(xc.style, {
position: 'absolute',
left: (numX * 24) + 'px',
visibility: xstate
});
xc.childNodes[0].textContent = Localization.localize('GRID_NUMBER', {
N: numX
});
}
if (c.offsetTop != (numY * 24)) {
var yc = gn('ycursor');
var ystate = ((numY < 0) || (numY > 14)) ? 'hidden' : 'visible';
setProps(yc.style, {
position: 'absolute',
top: (numY * 24) + 'px',
visibility: ystate
});
yc.childNodes[0].textContent = Localization.localize('GRID_NUMBER', {
N: 15 - numY
});
}
setProps(c.style, {
position: 'absolute',
top: (numY * 24) + 'px',
visibility: ystate
});
yc.childNodes[0].textContent = Localization.localize('GRID_NUMBER', {
N: 15 - numY
left: ((numX - 1) * 24) + 'px'
});
}
setProps(c.style, {
position: 'absolute',
top: (numY * 24) + 'px',
left: ((numX - 1) * 24) + 'px'
});
};
Grid.hide = function (b) {
Grid.hidden = b;
var mystate = Grid.hidden ? 'hidden' : 'visible';
gn('livegrid').style.visibility = mystate;
gn('rownum').style.visibility = mystate;
gn('colnum').style.visibility = mystate;
if (ScratchJr.stage.currentPage) {
mystate = !ScratchJr.getSprite() ? 'hidden' : mystate;
static hide (b) {
hidden = b;
var mystate = hidden ? 'hidden' : 'visible';
gn('livegrid').style.visibility = mystate;
gn('rownum').style.visibility = mystate;
gn('colnum').style.visibility = mystate;
if (ScratchJr.stage.currentPage) {
mystate = !ScratchJr.getSprite() ? 'hidden' : mystate;
}
gn('circlenum').style.visibility = mystate;
gn('xcursor').style.visibility = mystate;
gn('ycursor').style.visibility = mystate;
}
gn('circlenum').style.visibility = mystate;
gn('xcursor').style.visibility = mystate;
gn('ycursor').style.visibility = mystate;
};
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,349 +1,367 @@
var Record = function () {};
import ScratchJr from '../ScratchJr';
import Palette from './Palette';
import Undo from './Undo';
import iOS from '../../iPad/iOS';
import ScratchAudio from '../../utils/ScratchAudio';
import {frame, gn, newHTML, isTablet, isAndroid, setProps} from '../../utils/lib';
Record.isAndroid = isAndroid;
Record.interval = null;
Record.recordedSound = null;
Record.isRecording = false;
Record.isPlaying = false;
Record.available = true;
Record.error = false;
Record.dialogOpen = false;
Record.timeLimit = null;
Record.playTimeLimit = null;
let interval = null;
let recordedSound = null;
let isRecording = false;
let isPlaying = false;
let available = true;
let error = false;
let dialogOpen = false;
let timeLimit = null;
let playTimeLimit = null;
// Create the recording window, including buttons and volume indicators
Record.init = function () {
var modal = newHTML('div', 'record fade', frame);
modal.setAttribute('id', 'recorddialog');
var topbar = newHTML('div', 'toolbar', modal);
var actions = newHTML('div', 'actions', topbar);
newHTML('div', 'microphone', actions);
var buttons = newHTML('div', 'recordbuttons', actions);
var okbut = newHTML('div', 'recorddone', buttons);
if (isTablet) {
okbut.ontouchstart = Record.saveSoundAndClose;
} else {
okbut.onmousedown = Record.saveSoundAndClose;
export default class Record {
static get available () {
return available;
}
var sc = newHTML('div', 'soundbox', modal);
sc.setAttribute('id', 'soundbox');
var sv = newHTML('div', 'soundvolume', sc);
sv.setAttribute('id', 'soundvolume');
for (var i = 0; i < 13; i++) {
var si = newHTML('div', 'indicator', sv);
newHTML('div', 'soundlevel', si);
static set available (newAvailable) {
available = newAvailable;
}
var ctrol = newHTML('div', 'soundcontrols', sc);
ctrol.setAttribute('id', 'soundcontrols');
var lib = [['record', Record.record], ['stop', Record.stopSnd], ['play', Record.playSnd]];
for (var j = 0; j < lib.length; j++) {
Record.newToggleClicky(ctrol, 'id_', lib[j][0], lib[j][1]);
static get dialogOpen () {
return dialogOpen;
}
};
// Dialog box hide/show
Record.appear = function () {
gn('backdrop').setAttribute('class', 'modal-backdrop fade in');
setProps(gn('backdrop').style, {
display: 'block'
});
gn('recorddialog').setAttribute('class', 'record fade in');
ScratchJr.stopStrips();
Record.dialogOpen = true;
ScratchJr.onBackButtonCallback.push(Record.saveSoundandClose);
};
Record.disappear = function () {
setTimeout(function () {
gn('backdrop').setAttribute('class', 'modal-backdrop fade');
setProps(gn('backdrop').style, {
display: 'none'
});
gn('recorddialog').setAttribute('class', 'record fade');
}, 333);
Record.dialogOpen = false;
ScratchJr.onBackButtonCallback.pop();
};
// Register toggle buttons and handlers
Record.newToggleClicky = function (p, prefix, key, fcn) {
var button = newHTML('div', 'controlwrap', p);
newHTML('div', key + 'snd off', button);
button.setAttribute('type', 'toggleclicky');
button.setAttribute('id', prefix + key);
if (fcn) {
// Create the recording window, including buttons and volume indicators
static init () {
var modal = newHTML('div', 'record fade', frame);
modal.setAttribute('id', 'recorddialog');
var topbar = newHTML('div', 'toolbar', modal);
var actions = newHTML('div', 'actions', topbar);
newHTML('div', 'microphone', actions);
var buttons = newHTML('div', 'recordbuttons', actions);
var okbut = newHTML('div', 'recorddone', buttons);
if (isTablet) {
button.ontouchstart = function (evt) {
fcn(evt);
};
okbut.ontouchstart = Record.saveSoundAndClose;
} else {
button.onmousedown = function (evt) {
fcn(evt);
};
okbut.onmousedown = Record.saveSoundAndClose;
}
var sc = newHTML('div', 'soundbox', modal);
sc.setAttribute('id', 'soundbox');
var sv = newHTML('div', 'soundvolume', sc);
sv.setAttribute('id', 'soundvolume');
for (var i = 0; i < 13; i++) {
var si = newHTML('div', 'indicator', sv);
newHTML('div', 'soundlevel', si);
}
var ctrol = newHTML('div', 'soundcontrols', sc);
ctrol.setAttribute('id', 'soundcontrols');
var lib = [['record', Record.record], ['stop', Record.stopSnd], ['play', Record.playSnd]];
for (var j = 0; j < lib.length; j++) {
Record.newToggleClicky(ctrol, 'id_', lib[j][0], lib[j][1]);
}
}
return button;
};
// Toggle button appearance on/off
Record.toggleButtonUI = function (button, newState) {
var element = 'id_' + button;
var newStateStr = (newState) ? 'on' : 'off';
var attrclass = button + 'snd';
gn(element).childNodes[0].setAttribute('class', attrclass + ' ' + newStateStr);
};
// Dialog box hide/show
static appear () {
gn('backdrop').setAttribute('class', 'modal-backdrop fade in');
setProps(gn('backdrop').style, {
display: 'block'
});
gn('recorddialog').setAttribute('class', 'record fade in');
ScratchJr.stopStrips();
dialogOpen = true;
ScratchJr.onBackButtonCallback.push(Record.saveSoundandClose);
}
// Volume UI updater
Record.updateVolume = function (f) {
var num = Math.round(f * 13);
var div = gn('soundvolume');
if (!Record.isRecording) {
num = 0;
}
for (var i = 0; i < 13; i++) {
div.childNodes[i].childNodes[0].setAttribute('class', ((i > num) ? 'soundlevel off' : 'soundlevel on'));
}
};
// Stop recording UI and turn off volume levels
Record.recordUIoff = function () {
Record.toggleButtonUI('record', false);
var div = gn('soundvolume');
for (var i = 0; i < gn('soundvolume').childElementCount; i++) {
div.childNodes[i].childNodes[0].setAttribute('class', 'soundlevel off');
}
};
// On press record button
Record.record = function (e) {
if (Record.error) {
Record.killRecorder(e);
return;
}
if (Record.isPlaying) {
Record.stopPlayingSound(doRecord);
} else {
doRecord();
}
function doRecord () {
if (Record.isRecording) {
Record.stopRecording(); // Stop if we're already recording
} else {
iOS.sndrecord(Record.startRecording); // Start a recording
}
}
};
Record.startRecording = function (filename) {
if (parseInt(filename) < 0) {
// Error in getting record filename - go back to editor
Record.recordedSound = undefined;
Record.isRecording = false;
Record.killRecorder();
Palette.selectCategory(3);
} else {
// Save recording's filename for later
Record.recordedSound = filename;
Record.isRecording = true;
Record.error = false;
Record.soundname = filename;
Record.toggleButtonUI('record', true);
var poll = function () {
iOS.volume(Record.updateVolume, Record.recordError);
};
Record.interval = setInterval(poll, 33);
Record.timeLimit = setTimeout(function () {
if (Record.isRecording) {
Record.stopRecording();
}
}, 60000);
}
};
// Press the play button
Record.playSnd = function (e) {
if (Record.error) {
Record.killRecorder(e);
return;
}
if (!Record.recordedSound) {
return;
}
if (Record.isPlaying) {
Record.stopPlayingSound();
} else {
if (Record.isRecording) {
Record.stopRecording(Record.startPlaying);
} else {
Record.startPlaying();
}
}
};
// Start playing the sound and switch UI appropriately
Record.startPlaying = function () {
iOS.startplay(Record.timeOutPlay);
Record.toggleButtonUI('play', true);
Record.isPlaying = true;
};
// Gets the sound duration from iOS and changes play UI state after time
Record.timeOutPlay = function (timeout) {
if (parseInt(timeout) < 0) {
timeout = 0.1; // Error - stop playing immediately
}
Record.playTimeLimit = setTimeout(function () {
Record.toggleButtonUI('play', false);
Record.isPlaying = false;
}, timeout * 1000);
};
// Press on stop
Record.stopSnd = function (e) {
if (Record.error) {
Record.killRecorder(e);
return;
}
if (!Record.recordedSound) {
return;
}
Record.flashStopButton();
if (Record.isRecording) {
Record.stopRecording();
} else if (Record.isPlaying) {
Record.stopPlayingSound();
}
};
Record.flashStopButton = function () {
Record.toggleButtonUI('stop', true);
setTimeout(function () {
Record.toggleButtonUI('stop', false);
}, 200);
};
// Stop playing the sound and switch UI appropriately
Record.stopPlayingSound = function (fcn) {
iOS.stopplay(fcn);
Record.toggleButtonUI('play', false);
Record.isPlaying = false;
window.clearTimeout(Record.playTimeLimit);
Record.playTimeLimit = null;
};
// Stop the volume monitor and recording
Record.stopRecording = function (fcn) {
if (Record.timeLimit != null) {
clearTimeout(Record.timeLimit);
Record.timeLimit = null;
}
if (Record.interval != null) {
window.clearInterval(Record.interval);
Record.interval = null;
static disappear () {
setTimeout(function () {
Record.volumeCheckStopped(fcn);
}, 33);
} else {
Record.volumeCheckStopped(fcn);
gn('backdrop').setAttribute('class', 'modal-backdrop fade');
setProps(gn('backdrop').style, {
display: 'none'
});
gn('recorddialog').setAttribute('class', 'record fade');
}, 333);
dialogOpen = false;
ScratchJr.onBackButtonCallback.pop();
}
};
Record.volumeCheckStopped = function (fcn) {
Record.isRecording = false;
Record.recordUIoff();
iOS.recordstop(fcn);
};
// Press OK (check)
Record.saveSoundAndClose = function () {
if (Record.error || !Record.recordedSound) {
Record.killRecorder();
} else {
if (Record.isPlaying) {
Record.stopPlayingSound(Record.closeContinueSave);
} else {
if (Record.isRecording) {
Record.stopRecording(Record.closeContinueSave);
// Register toggle buttons and handlers
static newToggleClicky (p, prefix, key, fcn) {
var button = newHTML('div', 'controlwrap', p);
newHTML('div', key + 'snd off', button);
button.setAttribute('type', 'toggleclicky');
button.setAttribute('id', prefix + key);
if (fcn) {
if (isTablet) {
button.ontouchstart = function (evt) {
fcn(evt);
};
} else {
Record.closeContinueSave();
button.onmousedown = function (evt) {
fcn(evt);
};
}
}
return button;
}
// Toggle button appearance on/off
static toggleButtonUI (button, newState) {
var element = 'id_' + button;
var newStateStr = (newState) ? 'on' : 'off';
var attrclass = button + 'snd';
gn(element).childNodes[0].setAttribute('class', attrclass + ' ' + newStateStr);
}
// Volume UI updater
static updateVolume (f) {
var num = Math.round(f * 13);
var div = gn('soundvolume');
if (!isRecording) {
num = 0;
}
for (var i = 0; i < 13; i++) {
div.childNodes[i].childNodes[0].setAttribute('class', ((i > num) ? 'soundlevel off' : 'soundlevel on'));
}
}
// Stop recording UI and turn off volume levels
static recordUIoff () {
Record.toggleButtonUI('record', false);
var div = gn('soundvolume');
for (var i = 0; i < gn('soundvolume').childElementCount; i++) {
div.childNodes[i].childNodes[0].setAttribute('class', 'soundlevel off');
}
}
// On press record button
static record (e) {
if (error) {
Record.killRecorder(e);
return;
}
if (isPlaying) {
Record.stopPlayingSound(doRecord);
} else {
doRecord();
}
function doRecord () {
if (isRecording) {
Record.stopRecording(); // Stop if we're already recording
} else {
iOS.sndrecord(Record.startRecording); // Start a recording
}
}
}
};
Record.closeContinueSave = function () {
iOS.recorddisappear('YES', Record.getUserSound);
};
Record.closeContinueRemove = function () {
// don't get the sound - proceed right to tearDown
iOS.recorddisappear('NO', Record.tearDownRecorder);
};
Record.getUserSound = function () {
Record.isRecording = false;
if (!Record.isAndroid) {
iOS.getmedia(Record.recordedSound, Record.registerProjectSound);
} else {
// On Android, just pass URL
Record.registerProjectSound(null);
}
};
Record.registerProjectSound = function (data) {
function loadingDone (snd) {
if (snd != 'error') {
var spr = ScratchJr.getSprite();
var page = spr.div.parentNode.owner;
spr.sounds.push(Record.recordedSound);
Undo.record({
action: 'recordsound',
who: spr.id,
where: page.id,
sound: Record.recordedSound
});
ScratchJr.storyStart('Record.registerProjectSound');
}
Record.tearDownRecorder();
Palette.selectCategory(3);
}
if (!Record.isAndroid) {
ScratchAudio.loadFromData(Record.recordedSound, data, loadingDone);
} else {
// On Android, just pass URL
ScratchAudio.loadFromLocal(Record.recordedSound, loadingDone);
}
};
// Called on error - remove everything and hide the recorder
Record.killRecorder = function () {
// Inform iOS and then tear-down
if (Record.isPlaying) {
Record.stopPlayingSound(Record.closeContinueRemove); // stop playing and tear-down
} else {
if (Record.isRecording) {
Record.stopRecording(Record.closeContinueRemove); // stop recording and tear-down
static startRecording (filename) {
if (parseInt(filename) < 0) {
// Error in getting record filename - go back to editor
recordedSound = undefined;
isRecording = false;
Record.killRecorder();
Palette.selectCategory(3);
} else {
Record.closeContinueRemove();
// Save recording's filename for later
recordedSound = filename;
isRecording = true;
error = false;
Record.soundname = filename;
Record.toggleButtonUI('record', true);
var poll = function () {
iOS.volume(Record.updateVolume, Record.recordError);
};
interval = setInterval(poll, 33);
timeLimit = setTimeout(function () {
if (isRecording) {
Record.stopRecording();
}
}, 60000);
}
}
};
Record.tearDownRecorder = function () {
// Clear errors
if (Record.error) {
Record.error = false;
// Press the play button
static playSnd (e) {
if (error) {
Record.killRecorder(e);
return;
}
if (!recordedSound) {
return;
}
if (isPlaying) {
Record.stopPlayingSound();
} else {
if (isRecording) {
Record.stopRecording(Record.startPlaying);
} else {
Record.startPlaying();
}
}
}
// Refresh audio context
ScratchAudio.firstTime = true;
Record.isRecording = false;
Record.recordedSound = null;
// Hide the dialog
Record.disappear();
};
// Called when the app is put into the background
Record.recordError = function () {
Record.error = true;
Record.killRecorder();
};
// Start playing the sound and switch UI appropriately
static startPlaying () {
iOS.startplay(Record.timeOutPlay);
Record.toggleButtonUI('play', true);
isPlaying = true;
}
// Gets the sound duration from iOS and changes play UI state after time
static timeOutPlay (timeout) {
if (parseInt(timeout) < 0) {
timeout = 0.1; // Error - stop playing immediately
}
playTimeLimit = setTimeout(function () {
Record.toggleButtonUI('play', false);
isPlaying = false;
}, timeout * 1000);
}
// Press on stop
static stopSnd (e) {
if (error) {
Record.killRecorder(e);
return;
}
if (!recordedSound) {
return;
}
Record.flashStopButton();
if (isRecording) {
Record.stopRecording();
} else if (isPlaying) {
Record.stopPlayingSound();
}
}
static flashStopButton () {
Record.toggleButtonUI('stop', true);
setTimeout(function () {
Record.toggleButtonUI('stop', false);
}, 200);
}
// Stop playing the sound and switch UI appropriately
static stopPlayingSound (fcn) {
iOS.stopplay(fcn);
Record.toggleButtonUI('play', false);
isPlaying = false;
window.clearTimeout(playTimeLimit);
playTimeLimit = null;
}
// Stop the volume monitor and recording
static stopRecording (fcn) {
if (timeLimit != null) {
clearTimeout(timeLimit);
timeLimit = null;
}
if (interval != null) {
window.clearInterval(interval);
interval = null;
setTimeout(function () {
Record.volumeCheckStopped(fcn);
}, 33);
} else {
Record.volumeCheckStopped(fcn);
}
}
static volumeCheckStopped (fcn) {
isRecording = false;
Record.recordUIoff();
iOS.recordstop(fcn);
}
// Press OK (check)
static saveSoundAndClose () {
if (error || !recordedSound) {
Record.killRecorder();
} else {
if (isPlaying) {
Record.stopPlayingSound(Record.closeContinueSave);
} else {
if (isRecording) {
Record.stopRecording(Record.closeContinueSave);
} else {
Record.closeContinueSave();
}
}
}
}
static closeContinueSave () {
iOS.recorddisappear('YES', Record.getUserSound);
}
static closeContinueRemove () {
// don't get the sound - proceed right to tearDown
iOS.recorddisappear('NO', Record.tearDownRecorder);
}
static getUserSound () {
isRecording = false;
if (!isAndroid) {
iOS.getmedia(recordedSound, Record.registerProjectSound);
} else {
// On Android, just pass URL
Record.registerProjectSound(null);
}
}
static registerProjectSound (data) {
function loadingDone (snd) {
if (snd != 'error') {
var spr = ScratchJr.getSprite();
var page = spr.div.parentNode.owner;
spr.sounds.push(recordedSound);
Undo.record({
action: 'recordsound',
who: spr.id,
where: page.id,
sound: recordedSound
});
ScratchJr.storyStart('Record.registerProjectSound');
}
Record.tearDownRecorder();
Palette.selectCategory(3);
}
if (!isAndroid) {
ScratchAudio.loadFromData(recordedSound, data, loadingDone);
} else {
// On Android, just pass URL
ScratchAudio.loadFromLocal(recordedSound, loadingDone);
}
}
// Called on error - remove everything and hide the recorder
static killRecorder () {
// Inform iOS and then tear-down
if (isPlaying) {
Record.stopPlayingSound(Record.closeContinueRemove); // stop playing and tear-down
} else {
if (isRecording) {
Record.stopRecording(Record.closeContinueRemove); // stop recording and tear-down
} else {
Record.closeContinueRemove();
}
}
}
static tearDownRecorder () {
// Clear errors
if (error) {
error = false;
}
// Refresh audio context
ScratchAudio.firstTime = true;
isRecording = false;
recordedSound = null;
// Hide the dialog
Record.disappear();
}
// Called when the app is put into the background
static recordError () {
error = true;
Record.killRecorder();
}
}

View file

@ -1,308 +1,328 @@
var ScriptsPane = function () {};
ScriptsPane.scroll = undefined;
import ScratchJr from '../ScratchJr';
import Project from './Project';
import Thumbs from './Thumbs';
import Palette from './Palette';
import Undo from './Undo';
import Events from '../../utils/Events';
import Scroll from './Scroll';
import Menu from './Menu';
import ScratchAudio from '../../utils/ScratchAudio';
import {frame, gn, localx, localy, newHTML, isTablet,
globalx, globaly, setCanvasSize, getDocumentHeight, frame} from '../../utils/lib';
ScriptsPane.watermark;
let scroll = undefined;
let watermark;
ScriptsPane.createScripts = function (parent) {
var div = newHTML('div', 'scripts', parent);
div.setAttribute('id', 'scripts');
ScriptsPane.watermark = newHTML('div', 'watermark', div);
var h = Math.max(getDocumentHeight(), frame.offsetHeight);
setCanvasSize(div, div.offsetWidth, h - div.offsetTop);
ScriptsPane.scroll = new Scroll(div, 'scriptscontainer', div.offsetWidth,
h - div.offsetTop, ScratchJr.getActiveScript, ScratchJr.getBlocks);
};
ScriptsPane.setActiveScript = function (sprname) {
var currentsc = gn(sprname + '_scripts');
if (!currentsc) {
// Sprite not found
return;
export default class ScriptsPane {
static get scroll () {
return scroll;
}
ScratchJr.stage.currentPage.setCurrentSprite(gn(sprname).owner);
currentsc.owner.activate();
currentsc.parentNode.ontouchstart = function (evt) {
currentsc.owner.scriptsMouseDown(evt);
};
ScriptsPane.scroll.update();
};
ScriptsPane.runBlock = function (e, div) {
e.preventDefault();
e.stopPropagation();
var b = div.owner.findFirst();
// if (b.aStart) b = b.next;
if (!b) {
return;
static get watermark () {
return watermark;
}
ScratchJr.runtime.addRunScript(ScratchJr.getSprite(), b);
ScratchJr.startCurrentPageStrips(['ontouch']);
ScratchJr.userStart = true;
};
ScriptsPane.prepareToDrag = function (e) {
e.preventDefault();
var pt = Events.getTargetPoint(e);
ScriptsPane.pickBlock(pt.x, pt.y, e);
};
static createScripts (parent) {
var div = newHTML('div', 'scripts', parent);
div.setAttribute('id', 'scripts');
watermark = newHTML('div', 'watermark', div);
var h = Math.max(getDocumentHeight(), frame.offsetHeight);
setCanvasSize(div, div.offsetWidth, h - div.offsetTop);
scroll = new Scroll(div, 'scriptscontainer', div.offsetWidth,
h - div.offsetTop, ScratchJr.getActiveScript, ScratchJr.getBlocks);
}
ScriptsPane.pickBlock = function (x, y, e) {
if (!ScratchJr.runtime.inactive()) {
ScratchJr.stopStrips();
}
ScriptsPane.cleanCarets();
ScratchJr.unfocus(e);
var sc = ScratchJr.getActiveScript().owner;
sc.dragList = sc.findGroup(Events.dragthumbnail.owner);
sc.flowCaret = null;
var sy = Events.dragthumbnail.parentNode.scrollTop;
var sx = Events.dragthumbnail.parentNode.scrollLeft;
Events.dragmousex = x;
Events.dragmousey = y;
var lpt = {
x: localx(Events.dragthumbnail.parentNode, x),
y: localy(Events.dragthumbnail.parentNode, y)
};
var mx = Events.dragmousex - globalx(Events.dragDiv) - lpt.x + Events.dragthumbnail.left;
var my = Events.dragmousey - globaly(Events.dragDiv) - lpt.y + Events.dragthumbnail.top;
var mtx = new WebKitCSSMatrix(window.getComputedStyle(Events.dragthumbnail).webkitTransform);
my -= sy;
mx -= sx;
Events.dragcanvas = Events.dragthumbnail;
Events.dragcanvas.origin = 'scripts';
Events.dragcanvas.startx = mtx.m41;
Events.dragcanvas.starty = mtx.m42;
if (!Events.dragcanvas.isReporter && Events.dragcanvas.parentNode) {
Events.dragcanvas.parentNode.removeChild(Events.dragcanvas);
}
Events.move3D(Events.dragcanvas, mx, my);
Events.dragcanvas.style.zIndex = ScratchJr.dragginLayer;
Events.dragDiv.appendChild(Events.dragcanvas);
var b = Events.dragcanvas.owner;
b.detachBlock();
// b.lift();
if (Events.dragcanvas.isReporter) {
return;
}
ScratchJr.getActiveScript().owner.prepareCaret(b);
for (var i = 1; i < sc.dragList.length; i++) {
b = sc.dragList[i];
var pos = new WebKitCSSMatrix(window.getComputedStyle(b.div).webkitTransform);
var dx = pos.m41 - mtx.m41;
var dy = pos.m42 - mtx.m42;
b.moveBlock(dx, dy);
// b.lift();
Events.dragcanvas.appendChild(b.div);
}
};
////////////////////////////////////////////////
// Events MouseMove
////////////////////////////////////////////////
ScriptsPane.draggingBlock = function (e) {
e.preventDefault();
var pt = Events.getTargetPoint(e);
var dx = pt.x - Events.dragmousex;
var dy = pt.y - Events.dragmousey;
Events.move3D(Events.dragcanvas, dx, dy);
ScriptsPane.blockFeedback(Events.dragcanvas.left, Events.dragcanvas.top, e);
};
ScriptsPane.blockFeedback = function (dx, dy, e) {
var script = ScratchJr.getActiveScript().owner;
var limit = gn('palette').parentNode.offsetTop + gn('palette').parentNode.offsetHeight;
var ycor = dy + Events.dragcanvas.offsetHeight;
if (ycor < limit) {
script.removeCaret();
} else {
script.removeCaret();
script.insertCaret(dx, dy);
}
var thumb;
switch (Palette.getLandingPlace(script.dragList[0].div, e)) {
case 'library':
thumb = Palette.getHittedThumb(script.dragList[0].div, gn('spritecc'));
if (thumb && (gn(thumb.owner).owner.type == ScratchJr.getSprite().type)) {
Thumbs.quickHighlight(thumb);
} else {
thumb = undefined;
static setActiveScript (sprname) {
var currentsc = gn(sprname + '_scripts');
if (!currentsc) {
// Sprite not found
return;
}
ScratchJr.stage.currentPage.setCurrentSprite(gn(sprname).owner);
currentsc.owner.activate();
currentsc.parentNode.ontouchstart = function (evt) {
currentsc.owner.scriptsMouseDown(evt);
};
scroll.update();
}
static runBlock (e, div) {
e.preventDefault();
e.stopPropagation();
var b = div.owner.findFirst();
// if (b.aStart) b = b.next;
if (!b) {
return;
}
ScratchJr.runtime.addRunScript(ScratchJr.getSprite(), b);
ScratchJr.startCurrentPageStrips(['ontouch']);
ScratchJr.userStart = true;
}
static prepareToDrag (e) {
e.preventDefault();
var pt = Events.getTargetPoint(e);
ScriptsPane.pickBlock(pt.x, pt.y, e);
}
static pickBlock (x, y, e) {
if (!ScratchJr.runtime.inactive()) {
ScratchJr.stopStrips();
}
ScriptsPane.cleanCarets();
ScratchJr.unfocus(e);
var sc = ScratchJr.getActiveScript().owner;
sc.dragList = sc.findGroup(Events.dragthumbnail.owner);
sc.flowCaret = null;
var sy = Events.dragthumbnail.parentNode.scrollTop;
var sx = Events.dragthumbnail.parentNode.scrollLeft;
Events.dragmousex = x;
Events.dragmousey = y;
var lpt = {
x: localx(Events.dragthumbnail.parentNode, x),
y: localy(Events.dragthumbnail.parentNode, y)
};
var mx = Events.dragmousex - globalx(Events.dragDiv) - lpt.x + Events.dragthumbnail.left;
var my = Events.dragmousey - globaly(Events.dragDiv) - lpt.y + Events.dragthumbnail.top;
var mtx = new WebKitCSSMatrix(window.getComputedStyle(Events.dragthumbnail).webkitTransform);
my -= sy;
mx -= sx;
Events.dragcanvas = Events.dragthumbnail;
Events.dragcanvas.origin = 'scripts';
Events.dragcanvas.startx = mtx.m41;
Events.dragcanvas.starty = mtx.m42;
if (!Events.dragcanvas.isReporter && Events.dragcanvas.parentNode) {
Events.dragcanvas.parentNode.removeChild(Events.dragcanvas);
}
Events.move3D(Events.dragcanvas, mx, my);
Events.dragcanvas.style.zIndex = ScratchJr.dragginLayer;
Events.dragDiv.appendChild(Events.dragcanvas);
var b = Events.dragcanvas.owner;
b.detachBlock();
// b.lift();
if (Events.dragcanvas.isReporter) {
return;
}
ScratchJr.getActiveScript().owner.prepareCaret(b);
for (var i = 1; i < sc.dragList.length; i++) {
b = sc.dragList[i];
var pos = new WebKitCSSMatrix(window.getComputedStyle(b.div).webkitTransform);
var dx = pos.m41 - mtx.m41;
var dy = pos.m42 - mtx.m42;
b.moveBlock(dx, dy);
// b.lift();
Events.dragcanvas.appendChild(b.div);
}
}
////////////////////////////////////////////////
// Events MouseMove
////////////////////////////////////////////////
static draggingBlock (e) {
e.preventDefault();
var pt = Events.getTargetPoint(e);
var dx = pt.x - Events.dragmousex;
var dy = pt.y - Events.dragmousey;
Events.move3D(Events.dragcanvas, dx, dy);
ScriptsPane.blockFeedback(Events.dragcanvas.left, Events.dragcanvas.top, e);
}
static blockFeedback (dx, dy, e) {
var script = ScratchJr.getActiveScript().owner;
var limit = gn('palette').parentNode.offsetTop + gn('palette').parentNode.offsetHeight;
var ycor = dy + Events.dragcanvas.offsetHeight;
if (ycor < limit) {
script.removeCaret();
} else {
script.removeCaret();
script.insertCaret(dx, dy);
}
var thumb;
switch (Palette.getLandingPlace(script.dragList[0].div, e)) {
case 'library':
thumb = Palette.getHittedThumb(script.dragList[0].div, gn('spritecc'));
if (thumb && (gn(thumb.owner).owner.type == ScratchJr.getSprite().type)) {
Thumbs.quickHighlight(thumb);
} else {
thumb = undefined;
}
for (var i = 0; i < gn('spritecc').childElementCount; i++) {
var spr = gn('spritecc').childNodes[i];
if (spr.nodeName == 'FORM') {
continue;
}
if (thumb && (thumb.id != spr.id)) {
Thumbs.quickRestore(spr);
}
}
break;
default:
ScriptsPane.removeLibCaret();
break;
}
}
////////////////////////////////////////////////
// Events MouseUP
////////////////////////////////////////////////
static dropBlock (e, el) {
e.preventDefault();
var sc = ScratchJr.getActiveScript();
var spr = sc.owner.spr.id;
var page = ScratchJr.stage.currentPage;
switch (Palette.getLandingPlace(el, e)) {
case 'scripts':
var dx = localx(sc, el.left);
var dy = localy(sc, el.top);
ScriptsPane.blockDropped(sc, dx, dy);
break;
case 'library':
var thumb = Palette.getHittedThumb(el, gn('spritecc'));
ScriptsPane.blockDropped(ScratchJr.getActiveScript(), el.startx, el.starty);
if (thumb && (gn(thumb.owner).owner.type == gn(page.currentSpriteName).owner.type)) {
ScratchJr.storyStart('ScriptsPane.dropBlock:library');
ScratchAudio.sndFX('copy.wav');
Thumbs.quickHighlight(thumb);
setTimeout(function () {
Thumbs.quickRestore(thumb);
}, 300);
sc = gn(thumb.owner + '_scripts').owner;
var strip = Project.encodeStrip(el.owner);
var firstblock = strip[0];
var delta = sc.gettopblocks().length * 3;
firstblock[2] = firstblock[2] + delta;
firstblock[3] = firstblock[3] + delta;
sc.recreateStrip(strip);
spr = thumb.owner;
}
break;
default:
ScratchJr.getActiveScript().owner.deleteBlocks();
scroll.adjustCanvas();
scroll.refresh();
scroll.fitToScreen();
break;
}
Undo.record({
action: 'scripts',
where: page.id,
who: spr
});
ScratchJr.getActiveScript().owner.dragList = [];
}
static blockDropped (sc, dx, dy) {
Events.dragcanvas.style.zIndex = '';
var script = ScratchJr.getActiveScript().owner;
ScriptsPane.cleanCarets();
script.addBlockToScripts(Events.dragcanvas, dx, dy);
script.layout(Events.dragcanvas.owner);
if (sc.id == ScratchJr.getActiveScript().id) {
scroll.adjustCanvas();
scroll.refresh();
scroll.bounceBack();
}
}
static cleanCarets () {
ScratchJr.getActiveScript().owner.removeCaret();
ScriptsPane.removeLibCaret();
}
static removeLibCaret () {
for (var i = 0; i < gn('spritecc').childElementCount; i++) {
var spr = gn('spritecc').childNodes[i];
if (spr.nodeName == 'FORM') {
continue;
}
if (thumb && (thumb.id != spr.id)) {
Thumbs.quickRestore(spr);
Thumbs.quickRestore(spr);
}
}
//----------------------------------
// Drag Script Background
//----------------------------------
static dragBackground (e) {
if (Menu.openMenu) {
return;
}
if (isTablet && e.touches && (e.touches.length > 1)) {
return;
}
e.preventDefault();
e.stopPropagation();
var sc = ScratchJr.getActiveScript();
sc.top = sc.offsetTop;
sc.left = sc.offsetLeft;
var pt = Events.getTargetPoint(e);
Events.dragmousex = pt.x;
Events.dragmousey = pt.y;
Events.dragged = false;
ScriptsPane.setDragBackgroundEvents(ScriptsPane.dragMove, ScriptsPane.dragEnd);
}
static setDragBackgroundEvents (fcnmove, fcnup) {
if (isTablet) { // setDragBackgroundEvents
window.ontouchmove = function (evt) {
fcnmove(evt);
};
window.ontouchend = function (evt) {
fcnup(evt);
};
} else {
window.onmousemove = function (evt) {
fcnmove(evt);
};
window.onmouseup = function (evt) {
fcnup(evt);
};
}
}
static dragMove (e) {
var pt = Events.getTargetPoint(e);
if (!Events.dragged && (Events.distance(Events.dragmousex - pt.x, Events.dragmousey - pt.y) < 5)) {
return;
}
Events.dragged = true;
var dx = pt.x - Events.dragmousex;
var dy = pt.y - Events.dragmousey;
Events.dragmousex = pt.x;
Events.dragmousey = pt.y;
Events.move3D(ScratchJr.getActiveScript(), dx, dy);
scroll.refresh();
e.preventDefault();
}
static dragEnd (e) {
Events.dragged = false;
e.preventDefault();
Events.clearEvents();
scroll.bounceBack();
}
//////////////////////
//
//////////////////////
static updateScriptsPageBlocks (list) {
for (var j = 0; j < list.length; j++) {
if (!gn(list[j] + '_scripts')) {
continue;
}
var sc = gn(list[j] + '_scripts').owner;
if (!sc) {
continue;
}
var allblocks = sc.getBlocks();
for (var i = 0; i < allblocks.length; i++) {
allblocks[i].updateBlock();
}
}
break;
default:
ScriptsPane.removeLibCaret();
break;
}
};
////////////////////////////////////////////////
// Events MouseUP
////////////////////////////////////////////////
ScriptsPane.dropBlock = function (e, el) {
e.preventDefault();
var sc = ScratchJr.getActiveScript();
var spr = sc.owner.spr.id;
var page = ScratchJr.stage.currentPage;
switch (Palette.getLandingPlace(el, e)) {
case 'scripts':
var dx = localx(sc, el.left);
var dy = localy(sc, el.top);
ScriptsPane.blockDropped(sc, dx, dy);
break;
case 'library':
var thumb = Palette.getHittedThumb(el, gn('spritecc'));
ScriptsPane.blockDropped(ScratchJr.getActiveScript(), el.startx, el.starty);
if (thumb && (gn(thumb.owner).owner.type == gn(page.currentSpriteName).owner.type)) {
ScratchJr.storyStart('ScriptsPane.dropBlock:library');
ScratchAudio.sndFX('copy.wav');
Thumbs.quickHighlight(thumb);
setTimeout(function () {
Thumbs.quickRestore(thumb);
}, 300);
sc = gn(thumb.owner + '_scripts').owner;
var strip = Project.encodeStrip(el.owner);
var firstblock = strip[0];
var delta = sc.gettopblocks().length * 3;
firstblock[2] = firstblock[2] + delta;
firstblock[3] = firstblock[3] + delta;
sc.recreateStrip(strip);
spr = thumb.owner;
}
break;
default:
ScratchJr.getActiveScript().owner.deleteBlocks();
ScriptsPane.scroll.adjustCanvas();
ScriptsPane.scroll.refresh();
ScriptsPane.scroll.fitToScreen();
break;
}
Undo.record({
action: 'scripts',
where: page.id,
who: spr
});
ScratchJr.getActiveScript().owner.dragList = [];
};
ScriptsPane.blockDropped = function (sc, dx, dy) {
Events.dragcanvas.style.zIndex = '';
var script = ScratchJr.getActiveScript().owner;
ScriptsPane.cleanCarets();
script.addBlockToScripts(Events.dragcanvas, dx, dy);
script.layout(Events.dragcanvas.owner);
if (sc.id == ScratchJr.getActiveScript().id) {
ScriptsPane.scroll.adjustCanvas();
ScriptsPane.scroll.refresh();
ScriptsPane.scroll.bounceBack();
}
};
ScriptsPane.cleanCarets = function () {
ScratchJr.getActiveScript().owner.removeCaret();
ScriptsPane.removeLibCaret();
};
ScriptsPane.removeLibCaret = function () {
for (var i = 0; i < gn('spritecc').childElementCount; i++) {
var spr = gn('spritecc').childNodes[i];
if (spr.nodeName == 'FORM') {
continue;
}
Thumbs.quickRestore(spr);
}
};
//----------------------------------
// Drag Script Background
//----------------------------------
ScriptsPane.dragBackground = function (e) {
if (Menu.openMenu) {
return;
}
if (isTablet && e.touches && (e.touches.length > 1)) {
return;
}
e.preventDefault();
e.stopPropagation();
var sc = ScratchJr.getActiveScript();
sc.top = sc.offsetTop;
sc.left = sc.offsetLeft;
var pt = Events.getTargetPoint(e);
Events.dragmousex = pt.x;
Events.dragmousey = pt.y;
Events.dragged = false;
ScriptsPane.setDragBackgroundEvents(ScriptsPane.dragMove, ScriptsPane.dragEnd);
};
ScriptsPane.setDragBackgroundEvents = function (fcnmove, fcnup) {
if (isTablet) { // setDragBackgroundEvents
window.ontouchmove = function (evt) {
fcnmove(evt);
};
window.ontouchend = function (evt) {
fcnup(evt);
};
} else {
window.onmousemove = function (evt) {
fcnmove(evt);
};
window.onmouseup = function (evt) {
fcnup(evt);
};
}
};
ScriptsPane.dragMove = function (e) {
var pt = Events.getTargetPoint(e);
if (!Events.dragged && (Events.distance(Events.dragmousex - pt.x, Events.dragmousey - pt.y) < 5)) {
return;
}
Events.dragged = true;
var dx = pt.x - Events.dragmousex;
var dy = pt.y - Events.dragmousey;
Events.dragmousex = pt.x;
Events.dragmousey = pt.y;
Events.move3D(ScratchJr.getActiveScript(), dx, dy);
ScriptsPane.scroll.refresh();
e.preventDefault();
};
ScriptsPane.dragEnd = function (e) {
Events.dragged = false;
e.preventDefault();
Events.clearEvents();
ScriptsPane.scroll.bounceBack();
};
//////////////////////
//
//////////////////////
ScriptsPane.updateScriptsPageBlocks = function (list) {
for (var j = 0; j < list.length; j++) {
if (!gn(list[j] + '_scripts')) {
continue;
}
var sc = gn(list[j] + '_scripts').owner;
if (!sc) {
continue;
}
var allblocks = sc.getBlocks();
for (var i = 0; i < allblocks.length; i++) {
allblocks[i].updateBlock();
}
}
};
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,423 +1,431 @@
//////////////////////////////////
// Undo / Redo Functions
//////////////////////////////////
var Undo = function () {};
Undo.buffer = [];
Undo.index = 0;
Undo.aux = '';
Undo.tryCounter;
import ScratchJr from '../ScratchJr';
import Thumbs from './Thumbs';
import Project from './Project';
import Palette from './Palette';
import UI from './UI';
import ScratchAudio from '../../utils/ScratchAudio';
import {newHTML, isTablet, gn} from '../../utils/lib';
Undo.init = function () {
Undo.index = Undo.buffer.length;
Undo.update();
};
let buffer = [];
let index = 0;
let tryCounter;
Undo.setup = function (p) {
var div = newHTML('div', 'controlundo', p);
div.setAttribute('id', 'undocontrols');
var lib = [['undo', Undo.prevStep], ['redo', Undo.nextStep]];
for (var i = 0; i < lib.length; i++) {
Undo.newToggleClicky(div, 'id_', lib[i][0], lib[i][1]);
export default class Undo {
static init () {
index = buffer.length;
Undo.update();
}
Undo.update();
};
Undo.newToggleClicky = function (p, prefix, key, fcn) {
var div = newHTML('div', key + 'button', p);
div.setAttribute('type', 'toggleclicky');
div.setAttribute('id', prefix + key);
if (fcn) {
if (isTablet) {
div.ontouchstart = function (evt) {
fcn(evt);
};
} else {
div.onmousedown = function (evt) {
fcn(evt);
};
static setup (p) {
var div = newHTML('div', 'controlundo', p);
div.setAttribute('id', 'undocontrols');
var lib = [['undo', Undo.prevStep], ['redo', Undo.nextStep]];
for (var i = 0; i < lib.length; i++) {
Undo.newToggleClicky(div, 'id_', lib[i][0], lib[i][1]);
}
Undo.update();
}
return div;
};
Undo.record = function (obj) {
//console.log ("record", Undo.index, JSON.stringify(obj));
if (ScratchJr.getActiveScript()) {
ScratchJr.getActiveScript().owner.removeCaret();
}
if ((Undo.index + 1) <= Undo.buffer.length) {
Undo.buffer.splice(Undo.index + 1, Undo.buffer.length);
}
var data = Project.getUndo();
for (var key in obj) {
data[key] = obj[key];
}
Undo.buffer.push(data);
Undo.index++;
Undo.update();
// Project change state is usually tracked by looking if a particular action would record an undo
// We need slightly more specific behavior for story starters, so storyStarted is unaffected here.
ScratchJr.changed = true;
};
//////////////////////////////////
// Control buttons callbacks
//
////////////////////////////////
Undo.prevStep = function (e) {
if (isTablet && e.touches && (e.touches.length > 1)) {
return;
}
e.preventDefault();
e.stopPropagation();
ScratchJr.unfocus();
ScratchJr.time = e.timeStamp;
while (Undo.index >= Undo.buffer.length) {
Undo.index--;
}
Undo.index--;
var snd = (Undo.index < 0) ? 'boing.wav' : 'tap.wav';
ScratchAudio.sndFX(snd);
if (Undo.index < 0) {
Undo.index = 0;
} else {
Undo.smartRecreate('prev', Undo.buffer[Undo.index + 1], Undo.buffer[Undo.index]);
}
};
Undo.nextStep = function (e) {
if (isTablet && e.touches && (e.touches.length > 1)) {
return;
}
e.preventDefault();
e.stopPropagation();
ScratchJr.unfocus();
ScratchJr.time = e.timeStamp;
Undo.index++;
var snd = (Undo.index > Undo.buffer.length - 1) ? 'boing.wav' : 'tap.wav';
ScratchAudio.sndFX(snd);
if (Undo.index > Undo.buffer.length - 1) {
Undo.index = Undo.buffer.length - 1;
} else {
Undo.smartRecreate('next', Undo.buffer[Undo.index], Undo.buffer[Undo.index]);
}
};
Undo.smartRecreate = function (cmd, elem, data) {
ScratchJr.stopStrips();
var action = elem.action;
var page = elem.where;
var spr = elem.who;
// console.log (action, page, spr);
switch (action) {
case 'pageorder':
ScratchJr.stage.pages = Undo.getPageOrder(data);
Undo.recreateAllScripts(data);
ScratchJr.stage.setPage(gn(data.currentPage).owner, false);
if (Palette.numcat == 5) {
Palette.selectCategory(5);
}
break;
case 'changepage':
ScratchJr.stage.setPage(gn(data.currentPage).owner, false);
break;
case 'changebkg':
gn(page).owner.redoChangeBkg(data);
break;
case 'scripts':
Undo.redoScripts(data, page, spr);
if (spr && gn(spr)) {
gn(page).owner.setCurrentSprite(gn(spr).owner); // sets the variables
Thumbs.selectThisSprite(gn(spr).owner); // sets the UI
UI.resetSpriteLibrary();
}
break;
case 'deletepage':
case 'addpage':
if (data[page]) {
Undo.copyPage(data, page);
} else {
Undo.removePage(data, page);
}
break;
case 'deletesprite':
case 'copy':
if (data[page][spr]) {
Undo.copySprite(data, page, spr);
} else {
Undo.removeSprite(data, page, spr);
}
break;
case 'deletesound':
var sounds = data[page][spr].sounds.concat();
gn(spr).owner.sounds = sounds;
Undo.redoScripts(data, page, spr);
if (Palette.numcat == 3) {
Palette.selectCategory(3);
}
break;
case 'recordsound':
spr = gn((data[page][spr]).id).owner;
if (elem.sound && (spr.sounds.indexOf(elem.sound) > -1)) {
var indx = spr.sounds.indexOf(elem.sound);
if (indx > -1) {
spr.sounds.splice(indx, 1);
static newToggleClicky (p, prefix, key, fcn) {
var div = newHTML('div', key + 'button', p);
div.setAttribute('type', 'toggleclicky');
div.setAttribute('id', prefix + key);
if (fcn) {
if (isTablet) {
div.ontouchstart = function (evt) {
fcn(evt);
};
} else {
div.onmousedown = function (evt) {
fcn(evt);
};
}
} else {
spr.sounds.push(elem.sound);
}
if (Palette.numcat == 3) {
Palette.selectCategory(3);
}
break;
case 'edittext': // sprite delete or add
case 'modify':
Undo.removeSprite(data, page, spr);
if (data[page][spr]) {
Undo.copySprite(data, page, spr);
}
break;
default:
Project.clear();
Undo.recreate(Undo.buffer[Undo.index]);
break;
return div;
}
Undo.update();
};
Undo.copyPage = function (obj, page) {
var sc = ScratchJr.getSprite() ? gn(ScratchJr.stage.currentPage.currentSpriteName + '_scripts') : undefined;
if (sc) {
sc.owner.deactivate();
static record (obj) {
//console.log ("record", index, JSON.stringify(obj));
if (ScratchJr.getActiveScript()) {
ScratchJr.getActiveScript().owner.removeCaret();
}
if ((index + 1) <= buffer.length) {
buffer.splice(index + 1, buffer.length);
}
var data = Project.getUndo();
for (var key in obj) {
data[key] = obj[key];
}
buffer.push(data);
index++;
Undo.update();
// Project change state is usually tracked by looking if a particular action would record an undo
// We need slightly more specific behavior for story starters, so storyStarted is unaffected here.
ScratchJr.changed = true;
}
Project.recreatePage(page, obj[page], nextStep2);
function nextStep2 () {
ScratchJr.stage.pages = Undo.getPageOrder(obj);
ScratchJr.stage.setPage(gn(obj.currentPage).owner, false);
Undo.recreateAllScripts(obj);
var spritename = obj[obj.currentPage].lastSprite;
if (spritename && gn(spritename)) {
var spr = gn(spritename).owner;
var page = spr.div.parentNode.owner;
page.setCurrentSprite(spr);
Thumbs.selectThisSprite(spr);
//////////////////////////////////
// Control buttons callbacks
//
////////////////////////////////
static prevStep (e) {
if (isTablet && e.touches && (e.touches.length > 1)) {
return;
}
e.preventDefault();
e.stopPropagation();
ScratchJr.unfocus();
ScratchJr.time = e.timeStamp;
while (index >= buffer.length) {
index--;
}
index--;
var snd = (index < 0) ? 'boing.wav' : 'tap.wav';
ScratchAudio.sndFX(snd);
if (index < 0) {
index = 0;
} else {
Undo.smartRecreate('prev', buffer[index + 1], buffer[index]);
}
}
static nextStep (e) {
if (isTablet && e.touches && (e.touches.length > 1)) {
return;
}
e.preventDefault();
e.stopPropagation();
ScratchJr.unfocus();
ScratchJr.time = e.timeStamp;
index++;
var snd = (index > buffer.length - 1) ? 'boing.wav' : 'tap.wav';
ScratchAudio.sndFX(snd);
if (index > buffer.length - 1) {
index = buffer.length - 1;
} else {
Undo.smartRecreate('next', buffer[index], buffer[index]);
}
}
static smartRecreate (cmd, elem, data) {
ScratchJr.stopStrips();
var action = elem.action;
var page = elem.where;
var spr = elem.who;
// console.log (action, page, spr);
switch (action) {
case 'pageorder':
ScratchJr.stage.pages = Undo.getPageOrder(data);
Undo.recreateAllScripts(data);
ScratchJr.stage.setPage(gn(data.currentPage).owner, false);
if (Palette.numcat == 5) {
Palette.selectCategory(5);
}
break;
case 'changepage':
ScratchJr.stage.setPage(gn(data.currentPage).owner, false);
break;
case 'changebkg':
gn(page).owner.redoChangeBkg(data);
break;
case 'scripts':
Undo.redoScripts(data, page, spr);
if (spr && gn(spr)) {
gn(page).owner.setCurrentSprite(gn(spr).owner); // sets the variables
Thumbs.selectThisSprite(gn(spr).owner); // sets the UI
UI.resetSpriteLibrary();
}
break;
case 'deletepage':
case 'addpage':
if (data[page]) {
Undo.copyPage(data, page);
} else {
Undo.removePage(data, page);
}
break;
case 'deletesprite':
case 'copy':
if (data[page][spr]) {
Undo.copySprite(data, page, spr);
} else {
Undo.removeSprite(data, page, spr);
}
break;
case 'deletesound':
var sounds = data[page][spr].sounds.concat();
gn(spr).owner.sounds = sounds;
Undo.redoScripts(data, page, spr);
if (Palette.numcat == 3) {
Palette.selectCategory(3);
}
break;
case 'recordsound':
spr = gn((data[page][spr]).id).owner;
if (elem.sound && (spr.sounds.indexOf(elem.sound) > -1)) {
var indx = spr.sounds.indexOf(elem.sound);
if (indx > -1) {
spr.sounds.splice(indx, 1);
}
} else {
spr.sounds.push(elem.sound);
}
if (Palette.numcat == 3) {
Palette.selectCategory(3);
}
break;
case 'edittext': // sprite delete or add
case 'modify':
Undo.removeSprite(data, page, spr);
if (data[page][spr]) {
Undo.copySprite(data, page, spr);
}
break;
default:
Project.clear();
Undo.recreate(buffer[index]);
break;
}
Undo.update();
}
static copyPage (obj, page) {
var sc = ScratchJr.getSprite() ? gn(ScratchJr.stage.currentPage.currentSpriteName + '_scripts') : undefined;
if (sc) {
sc.owner.deactivate();
}
Project.recreatePage(page, obj[page], nextStep2);
function nextStep2 () {
ScratchJr.stage.pages = Undo.getPageOrder(obj);
ScratchJr.stage.setPage(gn(obj.currentPage).owner, false);
Undo.recreateAllScripts(obj);
var spritename = obj[obj.currentPage].lastSprite;
if (spritename && gn(spritename)) {
var spr = gn(spritename).owner;
var page = spr.div.parentNode.owner;
page.setCurrentSprite(spr);
Thumbs.selectThisSprite(spr);
if (Palette.numcat == 5) {
Palette.selectCategory(5);
}
}
}
}
};
Undo.getPageOrder = function (data) {
var pages = data.pages;
var res = [];
for (var i = 0; i < pages.length; i++) {
res.push(gn(pages[i]).owner);
static getPageOrder (data) {
var pages = data.pages;
var res = [];
for (var i = 0; i < pages.length; i++) {
res.push(gn(pages[i]).owner);
}
return res;
}
return res;
};
Undo.recreateAllScripts = function (data) {
for (var n = 0; n < data.pages.length; n++) {
var page = data[data.pages[n]];
var sprnames = page.sprites;
for (var i = 0; i < sprnames.length; i++) {
var spr = page[sprnames[i]];
if (!spr) {
continue;
static recreateAllScripts (data) {
for (var n = 0; n < data.pages.length; n++) {
var page = data[data.pages[n]];
var sprnames = page.sprites;
for (var i = 0; i < sprnames.length; i++) {
var spr = page[sprnames[i]];
if (!spr) {
continue;
}
if (spr.type != 'sprite') {
continue;
}
var sc = gn(spr.id + '_scripts');
if (!sc) {
continue;
}
Undo.redoScripts(data, data.pages[n], sprnames[i]);
}
if (spr.type != 'sprite') {
continue;
}
var sc = gn(spr.id + '_scripts');
if (!sc) {
continue;
}
Undo.redoScripts(data, data.pages[n], sprnames[i]);
}
}
};
Undo.removePage = function (data, str) {
if (!gn(str)) {
return;
}
var page = gn(str).owner;
if (!page) {
return;
}
ScratchJr.stage.removePageBlocks(str);
ScratchJr.stage.removePage(page);
ScratchJr.stage.pages = Undo.getPageOrder(data);
if (ScratchJr.stage.pages.length == 0) {
Undo.copyPage(data, data.currentPage);
} else {
ScratchJr.stage.setViewPage(gn(data.currentPage).owner);
Thumbs.updateSprites();
Thumbs.updatePages();
}
};
Undo.redoScripts = function (data, page, spr) {
var div = gn(spr + '_scripts');
while (div.childElementCount > 0) {
div.removeChild(div.childNodes[0]);
}
var sc = div.owner;
var list = data[page][spr].scripts;
for (var j = 0; j < list.length; j++) {
sc.recreateStrip(list[j]);
}
};
Undo.copySprite = function (data, page, spr) {
var obj = data[page][spr];
var fcn = function (spr) {
if (spr.type == 'sprite') {
if (page == ScratchJr.stage.currentPage.id) {
spr.div.style.visibility = 'visible';
}
Undo.setSprite(page, data);
static removePage (data, str) {
if (!gn(str)) {
return;
}
var page = gn(str).owner;
if (!page) {
return;
}
ScratchJr.stage.removePageBlocks(str);
ScratchJr.stage.removePage(page);
ScratchJr.stage.pages = Undo.getPageOrder(data);
if (ScratchJr.stage.pages.length == 0) {
Undo.copyPage(data, data.currentPage);
} else {
var delta = spr.fontsize * 1.35;
if (spr.homey == spr.page.textstartat) {
spr.page.textstartat += delta;
}
ScratchJr.stage.setViewPage(gn(data.currentPage).owner);
Thumbs.updateSprites();
Thumbs.updatePages();
}
};
Project.recreateObject(gn(page).owner, spr, obj, fcn, (data[page].lastSprite == spr));
};
}
Undo.setSprite = function (page, data) {
Thumbs.updatePages();
if (page != ScratchJr.stage.currentPage.id) {
return;
static redoScripts (data, page, spr) {
var div = gn(spr + '_scripts');
while (div.childElementCount > 0) {
div.removeChild(div.childNodes[0]);
}
var sc = div.owner;
var list = data[page][spr].scripts;
for (var j = 0; j < list.length; j++) {
sc.recreateStrip(list[j]);
}
}
var pageobj = gn(page).owner;
var lastspritename = data[page].lastSprite;
var lastsprite = lastspritename ? gn(lastspritename) : undefined;
if (!lastsprite) {
pageobj.setCurrentSprite(undefined);
} else {
var cs = lastsprite.owner;
pageobj.setCurrentSprite(cs);
UI.needsScroll();
Thumbs.updateSprites();
}
};
Undo.removeSprite = function (data, page, spr) {
if (!gn(spr)) {
return;
static copySprite (data, page, spr) {
var obj = data[page][spr];
var fcn = function (spr) {
if (spr.type == 'sprite') {
if (page == ScratchJr.stage.currentPage.id) {
spr.div.style.visibility = 'visible';
}
Undo.setSprite(page, data);
} else {
var delta = spr.fontsize * 1.35;
if (spr.homey == spr.page.textstartat) {
spr.page.textstartat += delta;
}
Thumbs.updatePages();
}
};
Project.recreateObject(gn(page).owner, spr, obj, fcn, (data[page].lastSprite == spr));
}
var sprite = gn(spr).owner;
var th = sprite.thumbnail;
ScratchJr.runtime.stopThreadSprite(sprite);
var pageobj = gn(page).owner;
var list = JSON.parse(pageobj.sprites);
var n = list.indexOf(spr);
list.splice(n, 1);
pageobj.sprites = JSON.stringify(list);
gn(spr).parentNode.removeChild(gn(spr));
if (!gn(spr + '_scripts')) {
static setSprite (page, data) {
Thumbs.updatePages();
return;
}
var sc = gn(spr + '_scripts');
if (sc) {
sc.parentNode.removeChild(sc);
}
if (th && th.parentNode) {
th.parentNode.removeChild(th);
}
Undo.setSprite(page, data);
};
Undo.recreate = function (data) {
Project.mediaCount = 0;
ScratchJr.stage.pages = [];
var pages = data.pages;
if (data.projectsounds) {
ScratchAudio.projectsounds = data.projectsounds;
}
for (var i = 0; i < pages.length; i++) {
Project.recreatePage(pages[i], data[pages[i]]);
}
Undo.loadPage(data.currentPage);
};
Undo.loadPage = function (pageid) {
var pages = ScratchJr.stage.getPagesID();
if (pages.indexOf(pageid) < 0) {
ScratchJr.stage.currentPage = ScratchJr.stage.pages[0];
} else {
ScratchJr.stage.currentPage = ScratchJr.stage.getPage(pageid);
}
ScratchJr.stage.currentPage.div.style.visibility = 'visible';
ScratchJr.stage.currentPage.setPageSprites('visible');
Undo.tryCounter = 100;
if (Project.mediaCount > 0) {
setTimeout(function () {
Undo.updateImages();
}, 20);
} else {
Undo.doneLoading();
}
};
Undo.updateImages = function () {
Undo.tryCounter--;
var done = (Project.mediaCount < 1) || (Undo.tryCounter < 1);
if (done) {
Undo.doneLoading();
} else {
setTimeout(function () {
Undo.updateImages();
}, 20);
}
};
Undo.flashIcon = function (div, press) {
div.setAttribute('class', press);
setTimeout(function () {
Undo.update();
}, 1000);
};
Undo.doneLoading = function () {
Thumbs.updateSprites();
Thumbs.updatePages();
};
Undo.update = function () {
if (gn('id_undo')) {
if (Undo.buffer.length == 1) {
Undo.tunOffButton(gn('id_undo'));
if (page != ScratchJr.stage.currentPage.id) {
return;
}
var pageobj = gn(page).owner;
var lastspritename = data[page].lastSprite;
var lastsprite = lastspritename ? gn(lastspritename) : undefined;
if (!lastsprite) {
pageobj.setCurrentSprite(undefined);
} else {
if (Undo.index < 1) {
var cs = lastsprite.owner;
pageobj.setCurrentSprite(cs);
UI.needsScroll();
Thumbs.updateSprites();
}
}
static removeSprite (data, page, spr) {
if (!gn(spr)) {
return;
}
var sprite = gn(spr).owner;
var th = sprite.thumbnail;
ScratchJr.runtime.stopThreadSprite(sprite);
var pageobj = gn(page).owner;
var list = JSON.parse(pageobj.sprites);
var n = list.indexOf(spr);
list.splice(n, 1);
pageobj.sprites = JSON.stringify(list);
gn(spr).parentNode.removeChild(gn(spr));
if (!gn(spr + '_scripts')) {
Thumbs.updatePages();
return;
}
var sc = gn(spr + '_scripts');
if (sc) {
sc.parentNode.removeChild(sc);
}
if (th && th.parentNode) {
th.parentNode.removeChild(th);
}
Undo.setSprite(page, data);
}
static recreate (data) {
Project.mediaCount = 0;
ScratchJr.stage.pages = [];
var pages = data.pages;
if (data.projectsounds) {
ScratchAudio.projectsounds = data.projectsounds;
}
for (var i = 0; i < pages.length; i++) {
Project.recreatePage(pages[i], data[pages[i]]);
}
Undo.loadPage(data.currentPage);
}
static loadPage (pageid) {
var pages = ScratchJr.stage.getPagesID();
if (pages.indexOf(pageid) < 0) {
ScratchJr.stage.currentPage = ScratchJr.stage.pages[0];
} else {
ScratchJr.stage.currentPage = ScratchJr.stage.getPage(pageid);
}
ScratchJr.stage.currentPage.div.style.visibility = 'visible';
ScratchJr.stage.currentPage.setPageSprites('visible');
tryCounter = 100;
if (Project.mediaCount > 0) {
setTimeout(function () {
Undo.updateImages();
}, 20);
} else {
Undo.doneLoading();
}
}
static updateImages () {
tryCounter--;
var done = (Project.mediaCount < 1) || (tryCounter < 1);
if (done) {
Undo.doneLoading();
} else {
setTimeout(function () {
Undo.updateImages();
}, 20);
}
}
static flashIcon (div, press) {
div.setAttribute('class', press);
setTimeout(function () {
Undo.update();
}, 1000);
}
static doneLoading () {
Thumbs.updateSprites();
Thumbs.updatePages();
}
static update () {
if (gn('id_undo')) {
if (buffer.length == 1) {
Undo.tunOffButton(gn('id_undo'));
} else {
Undo.tunOnButton(gn('id_undo'));
if (index < 1) {
Undo.tunOffButton(gn('id_undo'));
} else {
Undo.tunOnButton(gn('id_undo'));
}
}
if (index >= buffer.length - 1) {
Undo.tunOffButton(gn('id_redo'));
} else {
Undo.tunOnButton(gn('id_redo'));
}
}
if (Undo.index >= Undo.buffer.length - 1) {
Undo.tunOffButton(gn('id_redo'));
} else {
Undo.tunOnButton(gn('id_redo'));
}
}
};
Undo.tunOnButton = function (kid) {
var kclass = kid.getAttribute('class').split(' ')[0];
kid.setAttribute('class', kclass + ' enable');
};
static tunOnButton (kid) {
var kclass = kid.getAttribute('class').split(' ')[0];
kid.setAttribute('class', kclass + ' enable');
}
Undo.tunOffButton = function (kid) {
var kclass = kid.getAttribute('class').split(' ')[0];
kid.setAttribute('class', kclass + ' disable');
};
static tunOffButton (kid) {
var kclass = kid.getAttribute('class').split(' ')[0];
kid.setAttribute('class', kclass + ' disable');
}
}

View file

@ -626,7 +626,6 @@ export default class Paint {
ti.getBoundingClientRect().bottom * window.devicePixelRatio
);
}
Undo.aux = Project.getProject(ScratchJr.stage.currentPage.id);
setTimeout(function () {
ti.setSelectionRange(ti.value.length, ti.value.length);
}, 1);