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; let 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';
BlockSpecs.fontcolors = [BlockSpecs.fontred, BlockSpecs.fontorange, BlockSpecs.fontyellow, let loadassets = {};
BlockSpecs.fontdarkgreen, BlockSpecs.fontblue, BlockSpecs.fontpink, BlockSpecs.fontpurple, let fontwhite = '#f2f3f2';
BlockSpecs.fontwhite, BlockSpecs.fontdarkgray, BlockSpecs.fontblack]; 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']; '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']; 'LetterSend_Blue', 'LetterSend_Purple'];
BlockSpecs.speeds = ['speed0', 'speed1', 'speed2']; let speeds = ['speed0', 'speed1', 'speed2'];
BlockSpecs.initBlocks = function () { export default class BlockSpecs {
BlockSpecs.loadassets = new Object(); static get loadCount () {
BlockSpecs.loadGraphics(); return loadCount;
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'); static set loadCount (newLoadCount) {
loadCount = newLoadCount;
} }
IO.requestFromServer('assets/balloon.svg', BlockSpecs.setBalloon);
BlockSpecs.loadCount++;
};
BlockSpecs.setBalloon = function (str) { static get fontcolors () {
BlockSpecs.loadCount--; return fontcolors;
BlockSpecs.balloon = str; }
};
static get fontsizes () {
return fontsizes;
BlockSpecs.loadGraphics = function () { }
BlockSpecs.mic = BlockSpecs.getImageFrom('assets/ui/recordslot', 'svg');
BlockSpecs.yellowStart = BlockSpecs.getImageFrom('assets/blocks/start', 'svg'); static get speeds () {
BlockSpecs.yellowStartH = BlockSpecs.getImageFrom('assets/blocks/eh/startH'); return speeds;
}
BlockSpecs.yellowCmd = BlockSpecs.getImageFrom('assets/blocks/yellowCmd', 'svg');
BlockSpecs.yellowCmdH = BlockSpecs.getImageFrom('assets/blocks/eh/yellowCmdH'); static initBlocks () {
loadassets = new Object();
BlockSpecs.redEnd = BlockSpecs.getImageFrom('assets/blocks/endshort', 'svg'); BlockSpecs.loadGraphics();
BlockSpecs.redEndH = BlockSpecs.getImageFrom('assets/blocks/eh/stopH'); BlockSpecs.defs = BlockSpecs.setupBlocksSpecs();
BlockSpecs.palettes = BlockSpecs.setupPalettesDef();
BlockSpecs.orangeCmd = BlockSpecs.getImageFrom('assets/blocks/flow', 'svg'); BlockSpecs.categories = BlockSpecs.setupCategories();
BlockSpecs.orangeCmdH = BlockSpecs.getImageFrom('assets/blocks/eh/flowH'); if (Settings.edition == 'PBS') {
BlockSpecs.canvasMask = BlockSpecs.getImageFrom('assets/ui/canvasmask', 'svg');
BlockSpecs.limeCmd = BlockSpecs.getImageFrom('assets/blocks/sounds', 'svg'); } else {
BlockSpecs.limeCmdH = BlockSpecs.getImageFrom('assets/blocks/eh/soundsH'); BlockSpecs.canvasMask = BlockSpecs.getImageFrom('assets/ui/canvasmask');
}
BlockSpecs.pinkCmd = BlockSpecs.getImageFrom('assets/blocks/looks', 'svg'); if (Settings.edition != 'PBS') {
BlockSpecs.pinkCmdH = BlockSpecs.getImageFrom('assets/blocks/eh/looksH'); BlockSpecs.projectThumb = BlockSpecs.getImageFrom('assets/lobby/pmask');
}
BlockSpecs.redEndLong = BlockSpecs.getImageFrom('assets/blocks/endlong', 'svg'); IO.requestFromServer('assets/balloon.svg', BlockSpecs.setBalloon);
BlockSpecs.redEndLongH = BlockSpecs.getImageFrom('assets/blocks/eh/stoplongH'); loadCount++;
}
BlockSpecs.cShape = BlockSpecs.getImageFrom('assets/blocks/repeat');
BlockSpecs.cShapeH = BlockSpecs.getImageFrom('assets/blocks/eh/repeatH'); static setBalloon (str) {
loadCount--;
BlockSpecs.blueCmd = BlockSpecs.getImageFrom('assets/blocks/blueCmd', 'svg'); BlockSpecs.balloon = str;
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--;
};
} }
return img;
};
BlockSpecs.refreshLoading = function () { static loadGraphics () {
for (var key in BlockSpecs.loadassets) { BlockSpecs.mic = BlockSpecs.getImageFrom('assets/ui/recordslot', 'svg');
if (BlockSpecs.loadassets[key].complete) { BlockSpecs.yellowStart = BlockSpecs.getImageFrom('assets/blocks/start', 'svg');
BlockSpecs.loadCount--; 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 () { static setupCategories () {
return new Array( return new Array(
[ [
BlockSpecs.getImageFrom('assets/categories/StartOn', 'svg'), BlockSpecs.getImageFrom('assets/categories/StartOn', 'svg'),
BlockSpecs.getImageFrom('assets/categories/StartOff', 'svg'), BlockSpecs.getImageFrom('assets/categories/StartOff', 'svg'),
Settings.categoryStartColor Settings.categoryStartColor
], ],
[ [
BlockSpecs.getImageFrom('assets/categories/MotionOn', 'svg'), BlockSpecs.getImageFrom('assets/categories/MotionOn', 'svg'),
BlockSpecs.getImageFrom('assets/categories/MotionOff', 'svg'), BlockSpecs.getImageFrom('assets/categories/MotionOff', 'svg'),
Settings.categoryMotionColor Settings.categoryMotionColor
], ],
[ [
BlockSpecs.getImageFrom('assets/categories/LooksOn', 'svg'), BlockSpecs.getImageFrom('assets/categories/LooksOn', 'svg'),
BlockSpecs.getImageFrom('assets/categories/LooksOff', 'svg'), BlockSpecs.getImageFrom('assets/categories/LooksOff', 'svg'),
Settings.categoryLooksColor Settings.categoryLooksColor
], ],
[ [
BlockSpecs.getImageFrom('assets/categories/SoundOn', 'svg'), BlockSpecs.getImageFrom('assets/categories/SoundOn', 'svg'),
BlockSpecs.getImageFrom('assets/categories/SoundOff', 'svg'), BlockSpecs.getImageFrom('assets/categories/SoundOff', 'svg'),
Settings.categorySoundColor Settings.categorySoundColor
], ],
[ [
BlockSpecs.getImageFrom('assets/categories/FlowOn', 'svg'), BlockSpecs.getImageFrom('assets/categories/FlowOn', 'svg'),
BlockSpecs.getImageFrom('assets/categories/FlowOff', 'svg'), BlockSpecs.getImageFrom('assets/categories/FlowOff', 'svg'),
Settings.categoryFlowColor Settings.categoryFlowColor
], ],
[ [
BlockSpecs.getImageFrom('assets/categories/StopOn', 'svg'), BlockSpecs.getImageFrom('assets/categories/StopOn', 'svg'),
BlockSpecs.getImageFrom('assets/categories/StopOff', 'svg'), BlockSpecs.getImageFrom('assets/categories/StopOff', 'svg'),
Settings.categoryStopColor Settings.categoryStopColor
] ]
); );
}; }
BlockSpecs.setupPalettesDef = function () { static setupPalettesDef () {
return [['onflag', 'onclick', 'ontouch', 'onmessage', 'message'], return [['onflag', 'onclick', 'ontouch', 'onmessage', 'message'],
['forward', 'back', 'up', 'down', 'right', 'left', 'hop', 'home'], ['forward', 'back', 'up', 'down', 'right', 'left', 'hop', 'home'],
['say', 'space', 'grow', 'shrink', 'same', 'space', 'hide', 'show'], ['say', 'space', 'grow', 'shrink', 'same', 'space', 'hide', 'show'],
[], [],
['wait', 'stopmine', 'setspeed', 'repeat'], ['wait', 'stopmine', 'setspeed', 'repeat'],
['endstack', 'forever']]; ['endstack', 'forever']];
}; }
/////////////////////////////// ///////////////////////////////
// Data Structure // Data Structure
// //
// name - blocktype, icon or datastructure, blockshape, argtype, initial value, highlight, min, max, shadow // name - blocktype, icon or datastructure, blockshape, argtype, initial value, highlight, min, max, shadow
// //
// arg types: // arg types:
// null // null
// n -> number field; // n -> number field;
// t -> text field // t -> text field
// m --> image menu with argvalue equal to name; // m --> image menu with argvalue equal to name;
// d --> image menu with argvalue equal to number; // d --> image menu with argvalue equal to number;
// c -- > color drop down // c -- > color drop down
// s --> sound name // s --> sound name
// p --> page icon // p --> page icon
// //
//////////////////////////////// ////////////////////////////////
BlockSpecs.setupBlocksSpecs = function () { static setupBlocksSpecs () {
return { return {
'onflag': ['onflag', BlockSpecs.getImageFrom('assets/blockicons/greenFlag', 'svg'), 'onflag': ['onflag', BlockSpecs.getImageFrom('assets/blockicons/greenFlag', 'svg'),
BlockSpecs.yellowStart, null, null, BlockSpecs.yellowStartH, null, null, BlockSpecs.startS], BlockSpecs.yellowStart, null, null, BlockSpecs.yellowStartH, null, null, BlockSpecs.startS],
'onmessage': ['onmessage', BlockSpecs.getshapes, BlockSpecs.yellowStart, 'm', 'Orange', 'onmessage': ['onmessage', getshapes, BlockSpecs.yellowStart, 'm', 'Orange',
BlockSpecs.yellowStartH, null, null, BlockSpecs.startS], BlockSpecs.yellowStartH, null, null, BlockSpecs.startS],
'onclick': ['onclick', BlockSpecs.getImageFrom('assets/blockicons/OnTouch', 'svg'), 'onclick': ['onclick', BlockSpecs.getImageFrom('assets/blockicons/OnTouch', 'svg'),
BlockSpecs.yellowStart, null, null, BlockSpecs.yellowStartH, null, null, BlockSpecs.startS], BlockSpecs.yellowStart, null, null, BlockSpecs.yellowStartH, null, null, BlockSpecs.startS],
'ontouch': ['ontouch', BlockSpecs.getImageFrom('assets/blockicons/Bump', 'svg'), 'ontouch': ['ontouch', BlockSpecs.getImageFrom('assets/blockicons/Bump', 'svg'),
BlockSpecs.yellowStart, null, null, BlockSpecs.yellowStartH, null, null, BlockSpecs.startS], BlockSpecs.yellowStart, null, null, BlockSpecs.yellowStartH, null, null, BlockSpecs.startS],
'message': ['message', BlockSpecs.sendshapes, BlockSpecs.yellowCmd, 'm', 'Orange', 'message': ['message', sendshapes, BlockSpecs.yellowCmd, 'm', 'Orange',
BlockSpecs.yellowCmdH, null, null, BlockSpecs.cmdS], BlockSpecs.yellowCmdH, null, null, BlockSpecs.cmdS],
'repeat': ['repeat', BlockSpecs.getImageFrom('assets/blockicons/Repeat', 'svg'), 'repeat': ['repeat', BlockSpecs.getImageFrom('assets/blockicons/Repeat', 'svg'),
BlockSpecs.cShape, 'n', 4, BlockSpecs.cShapeH, 0, 24, BlockSpecs.repeatS], BlockSpecs.cShape, 'n', 4, BlockSpecs.cShapeH, 0, 24, BlockSpecs.repeatS],
'forward': ['forward', BlockSpecs.getImageFrom('assets/blockicons/Foward', 'svg'), 'forward': ['forward', BlockSpecs.getImageFrom('assets/blockicons/Foward', 'svg'),
BlockSpecs.blueCmd, 'n', 1, BlockSpecs.blueCmdH, -20, 20, BlockSpecs.cmdS], BlockSpecs.blueCmd, 'n', 1, BlockSpecs.blueCmdH, -20, 20, BlockSpecs.cmdS],
'back': ['back', BlockSpecs.getImageFrom('assets/blockicons/Back', 'svg'), 'back': ['back', BlockSpecs.getImageFrom('assets/blockicons/Back', 'svg'),
BlockSpecs.blueCmd, 'n', 1, BlockSpecs.blueCmdH, -20, 20, BlockSpecs.cmdS], BlockSpecs.blueCmd, 'n', 1, BlockSpecs.blueCmdH, -20, 20, BlockSpecs.cmdS],
'up': ['up', BlockSpecs.getImageFrom('assets/blockicons/Up', 'svg'), 'up': ['up', BlockSpecs.getImageFrom('assets/blockicons/Up', 'svg'),
BlockSpecs.blueCmd, 'n', 1, BlockSpecs.blueCmdH, -15, 15, BlockSpecs.cmdS], BlockSpecs.blueCmd, 'n', 1, BlockSpecs.blueCmdH, -15, 15, BlockSpecs.cmdS],
'down': ['down', BlockSpecs.getImageFrom('assets/blockicons/Down', 'svg'), 'down': ['down', BlockSpecs.getImageFrom('assets/blockicons/Down', 'svg'),
BlockSpecs.blueCmd, 'n', 1, BlockSpecs.blueCmdH, -15, 15, BlockSpecs.cmdS], BlockSpecs.blueCmd, 'n', 1, BlockSpecs.blueCmdH, -15, 15, BlockSpecs.cmdS],
'right': ['right', BlockSpecs.getImageFrom('assets/blockicons/Right', 'svg'), 'right': ['right', BlockSpecs.getImageFrom('assets/blockicons/Right', 'svg'),
BlockSpecs.blueCmd, 'n', 1, BlockSpecs.blueCmdH, -12, 12, BlockSpecs.cmdS], BlockSpecs.blueCmd, 'n', 1, BlockSpecs.blueCmdH, -12, 12, BlockSpecs.cmdS],
'left': ['left', BlockSpecs.getImageFrom('assets/blockicons/Left', 'svg'), 'left': ['left', BlockSpecs.getImageFrom('assets/blockicons/Left', 'svg'),
BlockSpecs.blueCmd, 'n', 1, BlockSpecs.blueCmdH, -12, 12, BlockSpecs.cmdS], BlockSpecs.blueCmd, 'n', 1, BlockSpecs.blueCmdH, -12, 12, BlockSpecs.cmdS],
'home': ['home', BlockSpecs.getImageFrom('assets/blockicons/Home', 'svg'), 'home': ['home', BlockSpecs.getImageFrom('assets/blockicons/Home', 'svg'),
BlockSpecs.blueCmd, null, null, BlockSpecs.blueCmdH, null, null, BlockSpecs.cmdS], BlockSpecs.blueCmd, null, null, BlockSpecs.blueCmdH, null, null, BlockSpecs.cmdS],
'hop': ['hop', BlockSpecs.getImageFrom('assets/blockicons/Hop', 'svg'), 'hop': ['hop', BlockSpecs.getImageFrom('assets/blockicons/Hop', 'svg'),
BlockSpecs.blueCmd, 'n', 2, BlockSpecs.blueCmdH, -15, 15, BlockSpecs.cmdS], BlockSpecs.blueCmd, 'n', 2, BlockSpecs.blueCmdH, -15, 15, BlockSpecs.cmdS],
'wait': ['wait', BlockSpecs.getImageFrom('assets/blockicons/Wait', 'svg'), 'wait': ['wait', BlockSpecs.getImageFrom('assets/blockicons/Wait', 'svg'),
BlockSpecs.orangeCmd, 'n', 10, BlockSpecs.orangeCmdH, 0, 50, BlockSpecs.cmdS], BlockSpecs.orangeCmd, 'n', 10, BlockSpecs.orangeCmdH, 0, 50, BlockSpecs.cmdS],
'setspeed': ['setspeed', BlockSpecs.speeds, BlockSpecs.orangeCmd, 'd', 1, 'setspeed': ['setspeed', speeds, BlockSpecs.orangeCmd, 'd', 1,
BlockSpecs.orangeCmdH, null, null, BlockSpecs.cmdS], BlockSpecs.orangeCmdH, null, null, BlockSpecs.cmdS],
'stopmine': ['stopmine', BlockSpecs.getImageFrom('assets/blockicons/Stop', 'svg'), 'stopmine': ['stopmine', BlockSpecs.getImageFrom('assets/blockicons/Stop', 'svg'),
BlockSpecs.orangeCmd, null, null, BlockSpecs.orangeCmdH, null, null, BlockSpecs.cmdS], BlockSpecs.orangeCmd, null, null, BlockSpecs.orangeCmdH, null, null, BlockSpecs.cmdS],
'say': ['say', BlockSpecs.getImageFrom('assets/blockicons/Say', 'svg'), 'say': ['say', BlockSpecs.getImageFrom('assets/blockicons/Say', 'svg'),
BlockSpecs.pinkCmd, 't', BlockSpecs.pinkCmd, 't',
Localization.localize('SAY_BLOCK_DEFAULT_ARGUMENT'), BlockSpecs.pinkCmdH, null, null, BlockSpecs.cmdS], Localization.localize('SAY_BLOCK_DEFAULT_ARGUMENT'), BlockSpecs.pinkCmdH, null, null, BlockSpecs.cmdS],
'show': ['show', BlockSpecs.getImageFrom('assets/blockicons/Appear', 'svg'), 'show': ['show', BlockSpecs.getImageFrom('assets/blockicons/Appear', 'svg'),
BlockSpecs.pinkCmd, null, null, BlockSpecs.pinkCmdH, null, null, BlockSpecs.cmdS], BlockSpecs.pinkCmd, null, null, BlockSpecs.pinkCmdH, null, null, BlockSpecs.cmdS],
'hide': ['hide', BlockSpecs.getImageFrom('assets/blockicons/Disappear', 'svg'), 'hide': ['hide', BlockSpecs.getImageFrom('assets/blockicons/Disappear', 'svg'),
BlockSpecs.pinkCmd, null, null, BlockSpecs.pinkCmdH, null, null, BlockSpecs.cmdS], BlockSpecs.pinkCmd, null, null, BlockSpecs.pinkCmdH, null, null, BlockSpecs.cmdS],
'grow': ['grow', BlockSpecs.getImageFrom('assets/blockicons/Grow', 'svg'), 'grow': ['grow', BlockSpecs.getImageFrom('assets/blockicons/Grow', 'svg'),
BlockSpecs.pinkCmd, 'n', 2, BlockSpecs.pinkCmdH, -10, 10, BlockSpecs.cmdS], BlockSpecs.pinkCmd, 'n', 2, BlockSpecs.pinkCmdH, -10, 10, BlockSpecs.cmdS],
'shrink': ['shrink', BlockSpecs.getImageFrom('assets/blockicons/Shrink', 'svg'), 'shrink': ['shrink', BlockSpecs.getImageFrom('assets/blockicons/Shrink', 'svg'),
BlockSpecs.pinkCmd, 'n', 2, BlockSpecs.pinkCmdH, -10, 10, BlockSpecs.cmdS], BlockSpecs.pinkCmd, 'n', 2, BlockSpecs.pinkCmdH, -10, 10, BlockSpecs.cmdS],
'same': ['same', BlockSpecs.getImageFrom('assets/blockicons/Reset', 'svg'), 'same': ['same', BlockSpecs.getImageFrom('assets/blockicons/Reset', 'svg'),
BlockSpecs.pinkCmd, null, null, BlockSpecs.pinkCmdH, null, null, BlockSpecs.cmdS], BlockSpecs.pinkCmd, null, null, BlockSpecs.pinkCmdH, null, null, BlockSpecs.cmdS],
'playsnd': ['playsnd', BlockSpecs.getImageFrom('assets/blockicons/Speaker', 'svg'), 'playsnd': ['playsnd', BlockSpecs.getImageFrom('assets/blockicons/Speaker', 'svg'),
BlockSpecs.limeCmd, 's', 'pop.mp3', BlockSpecs.limeCmdH, null, null, BlockSpecs.cmdS], BlockSpecs.limeCmd, 's', 'pop.mp3', BlockSpecs.limeCmdH, null, null, BlockSpecs.cmdS],
'playusersnd': ['playusersnd', BlockSpecs.getImageFrom('assets/blockicons/Microphone', 'svg'), 'playusersnd': ['playusersnd', BlockSpecs.getImageFrom('assets/blockicons/Microphone', 'svg'),
BlockSpecs.limeCmd, 'r', '1', BlockSpecs.limeCmdH, null, null, BlockSpecs.cmdS], BlockSpecs.limeCmd, 'r', '1', BlockSpecs.limeCmdH, null, null, BlockSpecs.cmdS],
'endstack': ['endstack', null, BlockSpecs.redEnd, null, null, BlockSpecs.redEndH, null, null, BlockSpecs.endS], 'endstack': ['endstack', null, BlockSpecs.redEnd, null, null,
'forever': ['forever', BlockSpecs.getImageFrom('assets/blockicons/Forever', 'svg'), BlockSpecs.redEndH, null, null, BlockSpecs.endS],
BlockSpecs.redEnd, null, null, BlockSpecs.redEndH, null, null, BlockSpecs.endS], 'forever': ['forever', BlockSpecs.getImageFrom('assets/blockicons/Forever', 'svg'),
'gotopage': ['gotopage', null, BlockSpecs.redEnd, null, null, BlockSpecs.redEndH, null, null, BlockSpecs.endS],
BlockSpecs.redEndLong, 'p', '2', BlockSpecs.redEndLongH, null, null, BlockSpecs.endLongS], 'gotopage': ['gotopage', null,
'caretstart': ['caretstart', null, BlockSpecs.redEndLong, 'p', '2', BlockSpecs.redEndLongH, null, null, BlockSpecs.endLongS],
BlockSpecs.getImageFrom('assets/blocks/caretstart', 'svg'), null, null, null, null, null], 'caretstart': ['caretstart', null,
'caretend': ['caretend', null, BlockSpecs.getImageFrom('assets/blocks/caretstart', 'svg'), null, null, null, null, null],
BlockSpecs.getImageFrom('assets/blocks/caretend', 'svg'), null, null, null, null, null], 'caretend': ['caretend', null,
'caretrepeat': ['caretrepeat', null, BlockSpecs.getImageFrom('assets/blocks/caretend', 'svg'), null, null, null, null, null],
BlockSpecs.getImageFrom('assets/blocks/caretrepeat'), null, null, null, null, null], 'caretrepeat': ['caretrepeat', null,
'caretcmd': ['caretcmd', null, BlockSpecs.getImageFrom('assets/blocks/caretrepeat'), null, null, null, null, null],
BlockSpecs.getImageFrom('assets/blocks/caretcmd', 'svg'), null, null, null, null, null] 'caretcmd': ['caretcmd', null,
BlockSpecs.getImageFrom('assets/blocks/caretcmd', 'svg'), null, null, null, null, null]
}; };
}; }
BlockSpecs.blockDesc = function (b, spr) { static blockDesc (b, spr) {
var str = b.getArgValue() ? b.getArgValue().toString() : (b.blocktype == 'playsnd') ? 'SOUND' : ''; var str = b.getArgValue() ? b.getArgValue().toString() : (b.blocktype == 'playsnd') ? 'SOUND' : '';
return { return {
'onflag': Localization.localize('BLOCK_DESC_GREEN_FLAG'), 'onflag': Localization.localize('BLOCK_DESC_GREEN_FLAG'),
'onclick': Localization.localize('BLOCK_DESC_ON_TAP', { 'onclick': Localization.localize('BLOCK_DESC_ON_TAP', {
CHARACTER_NAME: spr.name CHARACTER_NAME: spr.name
}), }),
'ontouch': Localization.localize('BLOCK_DESC_ON_BUMP', { 'ontouch': Localization.localize('BLOCK_DESC_ON_BUMP', {
CHARACTER_NAME: spr.name ? spr.name : '' CHARACTER_NAME: spr.name ? spr.name : ''
}), }),
'onmessage': Localization.localize('BLOCK_DESC_ON_MESSAGE', { 'onmessage': Localization.localize('BLOCK_DESC_ON_MESSAGE', {
COLOR: Localization.localize('BLOCK_DESC_MESSAGE_COLOR_ORANGE') COLOR: Localization.localize('BLOCK_DESC_MESSAGE_COLOR_ORANGE')
}), }),
'repeat': Localization.localize('BLOCK_DESC_REPEAT'), 'repeat': Localization.localize('BLOCK_DESC_REPEAT'),
'forward': Localization.localize('BLOCK_DESC_MOVE_RIGHT'), 'forward': Localization.localize('BLOCK_DESC_MOVE_RIGHT'),
'back': Localization.localize('BLOCK_DESC_MOVE_LEFT'), 'back': Localization.localize('BLOCK_DESC_MOVE_LEFT'),
'up': Localization.localize('BLOCK_DESC_MOVE_UP'), 'up': Localization.localize('BLOCK_DESC_MOVE_UP'),
'down': Localization.localize('BLOCK_DESC_MOVE_DOWN'), 'down': Localization.localize('BLOCK_DESC_MOVE_DOWN'),
'home': Localization.localize('BLOCK_DESC_GO_HOME'), 'home': Localization.localize('BLOCK_DESC_GO_HOME'),
'left': Localization.localize('BLOCK_DESC_TURN_LEFT'), 'left': Localization.localize('BLOCK_DESC_TURN_LEFT'),
'right': Localization.localize('BLOCK_DESC_TURN_RIGHT'), 'right': Localization.localize('BLOCK_DESC_TURN_RIGHT'),
'hop': Localization.localize('BLOCK_DESC_HOP'), 'hop': Localization.localize('BLOCK_DESC_HOP'),
'wait': Localization.localize('BLOCK_DESC_WAIT'), 'wait': Localization.localize('BLOCK_DESC_WAIT'),
'setspeed': Localization.localize('BLOCK_DESC_SET_SPEED'), 'setspeed': Localization.localize('BLOCK_DESC_SET_SPEED'),
'stopmine': Localization.localize('BLOCK_DESC_STOP', { 'stopmine': Localization.localize('BLOCK_DESC_STOP', {
CHARACTER_NAME: spr.name ? spr.name : spr.str CHARACTER_NAME: spr.name ? spr.name : spr.str
}), }),
'say': Localization.localize('BLOCK_DESC_SAY'), 'say': Localization.localize('BLOCK_DESC_SAY'),
'show': Localization.localize('BLOCK_DESC_SHOW'), 'show': Localization.localize('BLOCK_DESC_SHOW'),
'hide': Localization.localize('BLOCK_DESC_HIDE'), 'hide': Localization.localize('BLOCK_DESC_HIDE'),
'grow': Localization.localize('BLOCK_DESC_GROW'), 'grow': Localization.localize('BLOCK_DESC_GROW'),
'shrink': Localization.localize('BLOCK_DESC_SHRINK'), 'shrink': Localization.localize('BLOCK_DESC_SHRINK'),
'same': Localization.localize('BLOCK_DESC_RESET_SIZE'), 'same': Localization.localize('BLOCK_DESC_RESET_SIZE'),
'playsnd': Localization.localize('BLOCK_DESC_PLAY_SOUND', { 'playsnd': Localization.localize('BLOCK_DESC_PLAY_SOUND', {
SOUND_NAME: Localization.localize('BLOCK_DESC_PLAY_SOUND_POP') SOUND_NAME: Localization.localize('BLOCK_DESC_PLAY_SOUND_POP')
}), }),
'playusersnd': Localization.localize('BLOCK_DESC_PLAY_RECORDED_SOUND'), 'playusersnd': Localization.localize('BLOCK_DESC_PLAY_RECORDED_SOUND'),
'endstack': Localization.localize('BLOCK_DESC_END'), 'endstack': Localization.localize('BLOCK_DESC_END'),
'stopall': Localization.localize('BLOCK_DESC_STOP', { 'stopall': Localization.localize('BLOCK_DESC_STOP', {
CHARACTER_NAME: spr.name ? spr.name : '' CHARACTER_NAME: spr.name ? spr.name : ''
}), }),
'forever': Localization.localize('BLOCK_DESC_REPEAT_FOREVER'), 'forever': Localization.localize('BLOCK_DESC_REPEAT_FOREVER'),
'gotopage': Localization.localize('BLOCK_DESC_GO_TO_PAGE', { 'gotopage': Localization.localize('BLOCK_DESC_GO_TO_PAGE', {
PAGE: str PAGE: str
}), }),
'message': Localization.localize('BLOCK_DESC_SEND_MESSAGE', { 'message': Localization.localize('BLOCK_DESC_SEND_MESSAGE', {
COLOR: Localization.localize('BLOCK_DESC_MESSAGE_COLOR_ORANGE') 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) { export default class Menu {
var size = 50; static get openMenu () {
var color = b.owner.blocktype == 'setspeed' ? 'orange' : 'yellow'; return openMenu;
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);
}
Menu.openMenu = mu;
};
Menu.addImageToDropDown = function (mu, c, block, fcn) { static set openMenu (newOpenMenu) {
var img = BlockSpecs.getImageFrom('assets/blockicons/' + c, 'svg'); openMenu = newOpenMenu;
var cs = newHTML('div', 'ddchoice', mu); }
var micon = newHTML('canvas', undefined, cs);
var iconSize = 42; static openDropDown (b, fcn) {
var scaledIconSize = iconSize * window.devicePixelRatio; var size = 50;
setCanvasSize(micon, scaledIconSize, scaledIconSize); var color = b.owner.blocktype == 'setspeed' ? 'orange' : 'yellow';
setProps(micon.style, { var list = JSON.parse(b.owner.arg.list);
webkitTransform: 'translate(' + (-scaledIconSize / 2) + 'px, ' + (-scaledIconSize / 2) + 'px) ' + var num = b.owner.arg.numperrow;
'scale(' + (1 / window.devicePixelRatio) + ', ' + (1 / window.devicePixelRatio) + ') ' + var p = b.parentNode;
'translate(' + (scaledIconSize / 2) + 'px, ' + (scaledIconSize / 2) + 'px)' var dh = size * Math.round(list.length / num);
}); var rows = list.length / num;
if (!img.complete) { var w = size * list.length / rows;
img.onload = function () { 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); drawThumbnail(img, micon);
}; }
} else { if (isTablet) {
drawThumbnail(img, micon); 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) { static closeMyOpenMenu () {
handleTouchStart(evt); if (!openMenu) {
};
} 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; return;
} }
e.preventDefault(); openMenu.parentNode.removeChild(openMenu);
e.stopPropagation(); openMenu = undefined;
fcn(e, mu, block, c);
} }
}; }
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; var ti = document.forms.activetextbox.typing;
gn('textbox').style.visibility = 'visible'; gn('textbox').style.visibility = 'visible';
var me = this; var me = this;
Undo.aux = Project.getProject(ScratchJr.stage.currentPage.id);
ti.onblur = function () { ti.onblur = function () {
me.unfocusText(); 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 () { export default class Alert {
if (!Alert.balloon) { static get balloon () {
return; return balloon;
}
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;
} }
Alert.balloon = newCanvas(p, dx, dy, w, h, { static close () {
position: 'absolute', if (!balloon) {
zIndex: 2 return;
}); }
Alert.balloon.icon = obj; balloon.parentNode.removeChild(balloon);
var ctx = Alert.balloon.getContext('2d'); balloon = undefined;
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(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) { static open (p, obj, label, color) {
curve = 10; if (balloon) {
var path = new Array(['M', 0, curve], ['q', 0, -curve, curve, -curve], ['h', w - curve * 2], Alert.close();
['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], var scale = scaleMultiplier;
['q', -curve, 0, -curve, -curve], ['Z'] var w = 80;
); var h = 24;
ctx.clearRect(0, 0, Math.max(ctx.canvas.width, w), Math.max(ctx.canvas.height, h)); var dx = (globalx(obj, obj.offsetLeft) + (obj.offsetWidth / 2)) - (w + 7 * 2 + 4) * scale / 2;
ctx.fillStyle = color; var dy = globaly(obj, obj.offsetTop) - (24 * scale);
ctx.beginPath(); if (dy < 5 * scale) {
DrawPath.render(ctx, path); dy = 5 * scale;
ctx.fill(); }
};
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 // 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; let width = 482;
Grid.height = 362; let height = 362;
Grid.size = 24; let size = 24;
let hidden = true;
Grid.hidden = true; export default class Grid {
static get size () {
Grid.init = function (div) { return size;
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;
} }
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) { static get hidden () {
var row = newDiv(gn('stageframe'), 0, 0, w - 46 - 30, 24, { return hidden;
position: 'absolute', }
zIndex: ScratchJr.layerTop
}); static init (div) {
row.setAttribute('id', 'rownum'); var w = div.offsetWidth;
Grid.setScaleAndPosition(row, scaleMultiplier, 46 - 24, 75 + Grid.height, w - 46 - 30, 24); var h = div.offsetHeight;
var offset = Grid.size; var grid = newDiv(div, 0, 0, width, height, {
var dx = offset;
for (var i = 0; i < 480 / offset; i++) {
var num = newDiv(row, dx, 0, Grid.size, Grid.size, {
position: 'absolute', position: 'absolute',
zIndex: 10 zIndex: ScratchJr.layerTop
}); });
var p = newP(num, Localization.localize('GRID_NUMBER', { Grid.setScaleAndPosition(grid, scaleMultiplier, 47, 75, width, height);
N: (i + 1) grid.setAttribute('id', 'livegrid');
}), {}); Grid.drawLines(grid, width, height);
p.setAttribute('class', 'stylelabel'); Grid.createNumbering(w, h);
dx += offset; Grid.createCursor();
Grid.createYcursor();
Grid.createXcursor();
} }
var column = newDiv(gn('stageframe'), 0, 0, 24, h + 24, {
position: 'absolute', static setScaleAndPosition (grid, scale, x, y, w, h) {
zIndex: ScratchJr.layerTop setProps(grid.style, {
}); webkitTransform: 'translate(' + (-w / 2) + 'px, ' + (-h / 2) + 'px) ' +
column.setAttribute('id', 'colnum'); 'scale(' + scale + ') ' +
Grid.setScaleAndPosition(column, scaleMultiplier, 46 - 24, 74 + 1, 24, h + 24); 'translate(' + (w / 2 + x) + 'px, ' + (h / 2 + y) + 'px)'
var dy = 360 - offset; });
for (var j = 0; j < 360 / offset; j++) { }
var numj = newDiv(column, 0, dy, Grid.size, Grid.size, {
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', position: 'absolute',
zIndex: 10 zIndex: ScratchJr.layerTop
}); });
var py = newP(numj, Localization.localize('GRID_NUMBER', { row.setAttribute('id', 'rownum');
N: j + 1 Grid.setScaleAndPosition(row, scaleMultiplier, 46 - 24, 75 + height, w - 46 - 30, 24);
}), {}); var offset = size;
py.setAttribute('class', 'stylelabel'); var dx = offset;
dy -= offset; for (var i = 0; i < 480 / offset; i++) {
} var num = newDiv(row, dx, 0, size, size, {
}; position: 'absolute',
zIndex: 10
Grid.createYcursor = function () { });
var num = newDiv(gn('colnum'), 0, 0, Grid.size, Grid.size, { var p = newP(num, Localization.localize('GRID_NUMBER', {
position: 'absolute', N: (i + 1)
zIndex: 20 }), {});
}); p.setAttribute('class', 'stylelabel');
num.setAttribute('class', 'circle'); dx += offset;
num.style.background = '#6a99c1'; }
num.setAttribute('id', 'ycursor'); var column = newDiv(gn('stageframe'), 0, 0, 24, h + 24, {
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, {
position: 'absolute', position: 'absolute',
left: (numX * 24) + 'px', zIndex: ScratchJr.layerTop
visibility: xstate
});
xc.childNodes[0].textContent = Localization.localize('GRID_NUMBER', {
N: numX
}); });
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'); static createYcursor () {
var ystate = ((numY < 0) || (numY > 14)) ? 'hidden' : 'visible'; var num = newDiv(gn('colnum'), 0, 0, size, size, {
setProps(yc.style, { 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', position: 'absolute',
top: (numY * 24) + 'px', top: (numY * 24) + 'px',
visibility: ystate left: ((numX - 1) * 24) + 'px'
});
yc.childNodes[0].textContent = Localization.localize('GRID_NUMBER', {
N: 15 - numY
}); });
} }
setProps(c.style, {
position: 'absolute',
top: (numY * 24) + 'px',
left: ((numX - 1) * 24) + 'px'
});
};
Grid.hide = function (b) { static hide (b) {
Grid.hidden = b; hidden = b;
var mystate = Grid.hidden ? 'hidden' : 'visible'; var mystate = hidden ? 'hidden' : 'visible';
gn('livegrid').style.visibility = mystate; gn('livegrid').style.visibility = mystate;
gn('rownum').style.visibility = mystate; gn('rownum').style.visibility = mystate;
gn('colnum').style.visibility = mystate; gn('colnum').style.visibility = mystate;
if (ScratchJr.stage.currentPage) { if (ScratchJr.stage.currentPage) {
mystate = !ScratchJr.getSprite() ? 'hidden' : mystate; 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; let interval = null;
Record.interval = null; let recordedSound = null;
Record.recordedSound = null; let isRecording = false;
Record.isRecording = false; let isPlaying = false;
Record.isPlaying = false; let available = true;
Record.available = true; let error = false;
Record.error = false; let dialogOpen = false;
Record.dialogOpen = false; let timeLimit = null;
Record.timeLimit = null; let playTimeLimit = null;
Record.playTimeLimit = null;
// Create the recording window, including buttons and volume indicators export default class Record {
Record.init = function () { static get available () {
var modal = newHTML('div', 'record fade', frame); return available;
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;
} }
var sc = newHTML('div', 'soundbox', modal);
sc.setAttribute('id', 'soundbox'); static set available (newAvailable) {
var sv = newHTML('div', 'soundvolume', sc); available = newAvailable;
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'); static get dialogOpen () {
var lib = [['record', Record.record], ['stop', Record.stopSnd], ['play', Record.playSnd]]; return dialogOpen;
for (var j = 0; j < lib.length; j++) {
Record.newToggleClicky(ctrol, 'id_', lib[j][0], lib[j][1]);
} }
};
// Dialog box hide/show // Create the recording window, including buttons and volume indicators
Record.appear = function () { static init () {
gn('backdrop').setAttribute('class', 'modal-backdrop fade in'); var modal = newHTML('div', 'record fade', frame);
setProps(gn('backdrop').style, { modal.setAttribute('id', 'recorddialog');
display: 'block' var topbar = newHTML('div', 'toolbar', modal);
}); var actions = newHTML('div', 'actions', topbar);
gn('recorddialog').setAttribute('class', 'record fade in'); newHTML('div', 'microphone', actions);
ScratchJr.stopStrips(); var buttons = newHTML('div', 'recordbuttons', actions);
Record.dialogOpen = true; var okbut = newHTML('div', 'recorddone', buttons);
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) {
if (isTablet) { if (isTablet) {
button.ontouchstart = function (evt) { okbut.ontouchstart = Record.saveSoundAndClose;
fcn(evt);
};
} else { } else {
button.onmousedown = function (evt) { okbut.onmousedown = Record.saveSoundAndClose;
fcn(evt); }
}; 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 // Dialog box hide/show
Record.toggleButtonUI = function (button, newState) { static appear () {
var element = 'id_' + button; gn('backdrop').setAttribute('class', 'modal-backdrop fade in');
var newStateStr = (newState) ? 'on' : 'off'; setProps(gn('backdrop').style, {
var attrclass = button + 'snd'; display: 'block'
gn(element).childNodes[0].setAttribute('class', attrclass + ' ' + newStateStr); });
}; gn('recorddialog').setAttribute('class', 'record fade in');
ScratchJr.stopStrips();
dialogOpen = true;
ScratchJr.onBackButtonCallback.push(Record.saveSoundandClose);
}
// Volume UI updater static disappear () {
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;
setTimeout(function () { setTimeout(function () {
Record.volumeCheckStopped(fcn); gn('backdrop').setAttribute('class', 'modal-backdrop fade');
}, 33); setProps(gn('backdrop').style, {
} else { display: 'none'
Record.volumeCheckStopped(fcn); });
gn('recorddialog').setAttribute('class', 'record fade');
}, 333);
dialogOpen = false;
ScratchJr.onBackButtonCallback.pop();
} }
};
Record.volumeCheckStopped = function (fcn) { // Register toggle buttons and handlers
Record.isRecording = false; static newToggleClicky (p, prefix, key, fcn) {
Record.recordUIoff(); var button = newHTML('div', 'controlwrap', p);
iOS.recordstop(fcn); newHTML('div', key + 'snd off', button);
}; button.setAttribute('type', 'toggleclicky');
button.setAttribute('id', prefix + key);
// Press OK (check) if (fcn) {
Record.saveSoundAndClose = function () { if (isTablet) {
if (Record.error || !Record.recordedSound) { button.ontouchstart = function (evt) {
Record.killRecorder(); fcn(evt);
} else { };
if (Record.isPlaying) {
Record.stopPlayingSound(Record.closeContinueSave);
} else {
if (Record.isRecording) {
Record.stopRecording(Record.closeContinueSave);
} else { } 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 () { static startRecording (filename) {
iOS.recorddisappear('YES', Record.getUserSound); if (parseInt(filename) < 0) {
}; // Error in getting record filename - go back to editor
recordedSound = undefined;
Record.closeContinueRemove = function () { isRecording = false;
// don't get the sound - proceed right to tearDown Record.killRecorder();
iOS.recorddisappear('NO', Record.tearDownRecorder); Palette.selectCategory(3);
};
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
} else { } 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 () { // Press the play button
// Clear errors static playSnd (e) {
if (Record.error) { if (error) {
Record.error = false; 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 // Start playing the sound and switch UI appropriately
Record.recordError = function () { static startPlaying () {
Record.error = true; iOS.startplay(Record.timeOutPlay);
Record.killRecorder(); 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) { export default class ScriptsPane {
var div = newHTML('div', 'scripts', parent); static get scroll () {
div.setAttribute('id', 'scripts'); return scroll;
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;
} }
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) { static get watermark () {
e.preventDefault(); return watermark;
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;
};
ScriptsPane.prepareToDrag = function (e) { static createScripts (parent) {
e.preventDefault(); var div = newHTML('div', 'scripts', parent);
var pt = Events.getTargetPoint(e); div.setAttribute('id', 'scripts');
ScriptsPane.pickBlock(pt.x, pt.y, e); 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) { static setActiveScript (sprname) {
if (!ScratchJr.runtime.inactive()) { var currentsc = gn(sprname + '_scripts');
ScratchJr.stopStrips(); if (!currentsc) {
} // Sprite not found
ScriptsPane.cleanCarets(); return;
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;
} }
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++) { for (var i = 0; i < gn('spritecc').childElementCount; i++) {
var spr = gn('spritecc').childNodes[i]; var spr = gn('spritecc').childNodes[i];
if (spr.nodeName == 'FORM') { if (spr.nodeName == 'FORM') {
continue; 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 // Undo / Redo Functions
////////////////////////////////// //////////////////////////////////
var Undo = function () {};
Undo.buffer = []; import ScratchJr from '../ScratchJr';
Undo.index = 0; import Thumbs from './Thumbs';
Undo.aux = ''; import Project from './Project';
Undo.tryCounter; import Palette from './Palette';
import UI from './UI';
import ScratchAudio from '../../utils/ScratchAudio';
import {newHTML, isTablet, gn} from '../../utils/lib';
Undo.init = function () { let buffer = [];
Undo.index = Undo.buffer.length; let index = 0;
Undo.update(); let tryCounter;
};
Undo.setup = function (p) { export default class Undo {
var div = newHTML('div', 'controlundo', p); static init () {
div.setAttribute('id', 'undocontrols'); index = buffer.length;
var lib = [['undo', Undo.prevStep], ['redo', Undo.nextStep]]; Undo.update();
for (var i = 0; i < lib.length; i++) {
Undo.newToggleClicky(div, 'id_', lib[i][0], lib[i][1]);
} }
Undo.update();
};
Undo.newToggleClicky = function (p, prefix, key, fcn) { static setup (p) {
var div = newHTML('div', key + 'button', p); var div = newHTML('div', 'controlundo', p);
div.setAttribute('type', 'toggleclicky'); div.setAttribute('id', 'undocontrols');
div.setAttribute('id', prefix + key); var lib = [['undo', Undo.prevStep], ['redo', Undo.nextStep]];
if (fcn) { for (var i = 0; i < lib.length; i++) {
if (isTablet) { Undo.newToggleClicky(div, 'id_', lib[i][0], lib[i][1]);
div.ontouchstart = function (evt) {
fcn(evt);
};
} else {
div.onmousedown = function (evt) {
fcn(evt);
};
} }
Undo.update();
} }
return div;
};
Undo.record = function (obj) { static newToggleClicky (p, prefix, key, fcn) {
//console.log ("record", Undo.index, JSON.stringify(obj)); var div = newHTML('div', key + 'button', p);
if (ScratchJr.getActiveScript()) { div.setAttribute('type', 'toggleclicky');
ScratchJr.getActiveScript().owner.removeCaret(); div.setAttribute('id', prefix + key);
} if (fcn) {
if ((Undo.index + 1) <= Undo.buffer.length) { if (isTablet) {
Undo.buffer.splice(Undo.index + 1, Undo.buffer.length); div.ontouchstart = function (evt) {
} fcn(evt);
var data = Project.getUndo(); };
for (var key in obj) { } else {
data[key] = obj[key]; div.onmousedown = function (evt) {
} fcn(evt);
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);
} }
} else {
spr.sounds.push(elem.sound);
} }
if (Palette.numcat == 3) { return div;
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;
} }
Undo.update();
};
Undo.copyPage = function (obj, page) { static record (obj) {
var sc = ScratchJr.getSprite() ? gn(ScratchJr.stage.currentPage.currentSpriteName + '_scripts') : undefined; //console.log ("record", index, JSON.stringify(obj));
if (sc) { if (ScratchJr.getActiveScript()) {
sc.owner.deactivate(); 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); // Control buttons callbacks
ScratchJr.stage.setPage(gn(obj.currentPage).owner, false); //
Undo.recreateAllScripts(obj); ////////////////////////////////
var spritename = obj[obj.currentPage].lastSprite;
if (spritename && gn(spritename)) { static prevStep (e) {
var spr = gn(spritename).owner; if (isTablet && e.touches && (e.touches.length > 1)) {
var page = spr.div.parentNode.owner; return;
page.setCurrentSprite(spr); }
Thumbs.selectThisSprite(spr); 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) { if (Palette.numcat == 5) {
Palette.selectCategory(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) { static getPageOrder (data) {
var pages = data.pages; var pages = data.pages;
var res = []; var res = [];
for (var i = 0; i < pages.length; i++) { for (var i = 0; i < pages.length; i++) {
res.push(gn(pages[i]).owner); res.push(gn(pages[i]).owner);
}
return res;
} }
return res;
};
Undo.recreateAllScripts = function (data) { static recreateAllScripts (data) {
for (var n = 0; n < data.pages.length; n++) { for (var n = 0; n < data.pages.length; n++) {
var page = data[data.pages[n]]; var page = data[data.pages[n]];
var sprnames = page.sprites; var sprnames = page.sprites;
for (var i = 0; i < sprnames.length; i++) { for (var i = 0; i < sprnames.length; i++) {
var spr = page[sprnames[i]]; var spr = page[sprnames[i]];
if (!spr) { if (!spr) {
continue; 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) { static removePage (data, str) {
if (!gn(str)) { if (!gn(str)) {
return; return;
} }
var page = gn(str).owner; var page = gn(str).owner;
if (!page) { if (!page) {
return; return;
} }
ScratchJr.stage.removePageBlocks(str); ScratchJr.stage.removePageBlocks(str);
ScratchJr.stage.removePage(page); ScratchJr.stage.removePage(page);
ScratchJr.stage.pages = Undo.getPageOrder(data); ScratchJr.stage.pages = Undo.getPageOrder(data);
if (ScratchJr.stage.pages.length == 0) { if (ScratchJr.stage.pages.length == 0) {
Undo.copyPage(data, data.currentPage); 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);
} else { } else {
var delta = spr.fontsize * 1.35; ScratchJr.stage.setViewPage(gn(data.currentPage).owner);
if (spr.homey == spr.page.textstartat) { Thumbs.updateSprites();
spr.page.textstartat += delta;
}
Thumbs.updatePages(); Thumbs.updatePages();
} }
}; }
Project.recreateObject(gn(page).owner, spr, obj, fcn, (data[page].lastSprite == spr));
};
Undo.setSprite = function (page, data) { static redoScripts (data, page, spr) {
Thumbs.updatePages(); var div = gn(spr + '_scripts');
if (page != ScratchJr.stage.currentPage.id) { while (div.childElementCount > 0) {
return; 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) { static copySprite (data, page, spr) {
if (!gn(spr)) { var obj = data[page][spr];
return; 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; static setSprite (page, data) {
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(); Thumbs.updatePages();
return; if (page != ScratchJr.stage.currentPage.id) {
} return;
var sc = gn(spr + '_scripts'); }
if (sc) { var pageobj = gn(page).owner;
sc.parentNode.removeChild(sc); var lastspritename = data[page].lastSprite;
} var lastsprite = lastspritename ? gn(lastspritename) : undefined;
if (th && th.parentNode) { if (!lastsprite) {
th.parentNode.removeChild(th); pageobj.setCurrentSprite(undefined);
}
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'));
} else { } 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')); Undo.tunOffButton(gn('id_undo'));
} else { } 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) { static tunOnButton (kid) {
var kclass = kid.getAttribute('class').split(' ')[0]; var kclass = kid.getAttribute('class').split(' ')[0];
kid.setAttribute('class', kclass + ' enable'); kid.setAttribute('class', kclass + ' enable');
}; }
Undo.tunOffButton = function (kid) { static tunOffButton (kid) {
var kclass = kid.getAttribute('class').split(' ')[0]; var kclass = kid.getAttribute('class').split(' ')[0];
kid.setAttribute('class', kclass + ' disable'); kid.setAttribute('class', kclass + ' disable');
}; }
}

View file

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