mirror of
https://github.com/scratchfoundation/scratchjr.git
synced 2024-11-25 08:38:30 -05:00
Modularize remaining objects with static methods
This commit is contained in:
parent
55d8b40691
commit
bf07d98ccd
15 changed files with 5662 additions and 5463 deletions
|
@ -1,306 +1,331 @@
|
|||
var BlockSpecs = function () {};
|
||||
import Localization from '../../utils/Localization';
|
||||
import IO from '../../iPad/IO';
|
||||
|
||||
BlockSpecs.loadCount = 0;
|
||||
BlockSpecs.loadassets = {};
|
||||
BlockSpecs.fontwhite = '#f2f3f2';
|
||||
BlockSpecs.fontpink = '#ff8ae9';
|
||||
BlockSpecs.fontdarkgray = '#6d6e6c';
|
||||
BlockSpecs.fontblack = '#1b2a34';
|
||||
BlockSpecs.fontyellow = '#ffdd33';
|
||||
BlockSpecs.fontdarkgreen = '#287f46';
|
||||
BlockSpecs.fontpurple = '#8f56e3';
|
||||
BlockSpecs.fontblue = '#0d50ab';
|
||||
BlockSpecs.fontred = '#c4281b';
|
||||
BlockSpecs.fontorange = '#da8540';
|
||||
let loadCount = 0;
|
||||
|
||||
BlockSpecs.fontcolors = [BlockSpecs.fontred, BlockSpecs.fontorange, BlockSpecs.fontyellow,
|
||||
BlockSpecs.fontdarkgreen, BlockSpecs.fontblue, BlockSpecs.fontpink, BlockSpecs.fontpurple,
|
||||
BlockSpecs.fontwhite, BlockSpecs.fontdarkgray, BlockSpecs.fontblack];
|
||||
let loadassets = {};
|
||||
let fontwhite = '#f2f3f2';
|
||||
let fontpink = '#ff8ae9';
|
||||
let fontdarkgray = '#6d6e6c';
|
||||
let fontblack = '#1b2a34';
|
||||
let fontyellow = '#ffdd33';
|
||||
let fontdarkgreen = '#287f46';
|
||||
let fontpurple = '#8f56e3';
|
||||
let fontblue = '#0d50ab';
|
||||
let fontred = '#c4281b';
|
||||
let fontorange = '#da8540';
|
||||
|
||||
BlockSpecs.fontsizes = [16, 24, 36, 48, 56, 72];
|
||||
let fontcolors = [fontred, fontorange, fontyellow,
|
||||
fontdarkgreen, fontblue, fontpink, fontpurple,
|
||||
fontwhite, fontdarkgray, fontblack];
|
||||
|
||||
BlockSpecs.getshapes = ['LetterGet_Orange', 'LetterGet_Red', 'LetterGet_Yellow', 'LetterGet_Green',
|
||||
let fontsizes = [16, 24, 36, 48, 56, 72];
|
||||
|
||||
let getshapes = ['LetterGet_Orange', 'LetterGet_Red', 'LetterGet_Yellow', 'LetterGet_Green',
|
||||
'LetterGet_Blue', 'LetterGet_Purple'];
|
||||
BlockSpecs.sendshapes = ['LetterSend_Orange', 'LetterSend_Red', 'LetterSend_Yellow', 'LetterSend_Green',
|
||||
let sendshapes = ['LetterSend_Orange', 'LetterSend_Red', 'LetterSend_Yellow', 'LetterSend_Green',
|
||||
'LetterSend_Blue', 'LetterSend_Purple'];
|
||||
|
||||
BlockSpecs.speeds = ['speed0', 'speed1', 'speed2'];
|
||||
let speeds = ['speed0', 'speed1', 'speed2'];
|
||||
|
||||
BlockSpecs.initBlocks = function () {
|
||||
BlockSpecs.loadassets = new Object();
|
||||
BlockSpecs.loadGraphics();
|
||||
BlockSpecs.defs = BlockSpecs.setupBlocksSpecs();
|
||||
BlockSpecs.palettes = BlockSpecs.setupPalettesDef();
|
||||
BlockSpecs.categories = BlockSpecs.setupCategories();
|
||||
if (Settings.edition == 'PBS') {
|
||||
BlockSpecs.canvasMask = BlockSpecs.getImageFrom('assets/ui/canvasmask', 'svg');
|
||||
} else {
|
||||
BlockSpecs.canvasMask = BlockSpecs.getImageFrom('assets/ui/canvasmask');
|
||||
export default class BlockSpecs {
|
||||
static get loadCount () {
|
||||
return loadCount;
|
||||
}
|
||||
if (Settings.edition != 'PBS') {
|
||||
BlockSpecs.projectThumb = BlockSpecs.getImageFrom('assets/lobby/pmask');
|
||||
|
||||
static set loadCount (newLoadCount) {
|
||||
loadCount = newLoadCount;
|
||||
}
|
||||
IO.requestFromServer('assets/balloon.svg', BlockSpecs.setBalloon);
|
||||
BlockSpecs.loadCount++;
|
||||
};
|
||||
|
||||
BlockSpecs.setBalloon = function (str) {
|
||||
BlockSpecs.loadCount--;
|
||||
BlockSpecs.balloon = str;
|
||||
};
|
||||
|
||||
|
||||
BlockSpecs.loadGraphics = function () {
|
||||
BlockSpecs.mic = BlockSpecs.getImageFrom('assets/ui/recordslot', 'svg');
|
||||
BlockSpecs.yellowStart = BlockSpecs.getImageFrom('assets/blocks/start', 'svg');
|
||||
BlockSpecs.yellowStartH = BlockSpecs.getImageFrom('assets/blocks/eh/startH');
|
||||
|
||||
BlockSpecs.yellowCmd = BlockSpecs.getImageFrom('assets/blocks/yellowCmd', 'svg');
|
||||
BlockSpecs.yellowCmdH = BlockSpecs.getImageFrom('assets/blocks/eh/yellowCmdH');
|
||||
|
||||
BlockSpecs.redEnd = BlockSpecs.getImageFrom('assets/blocks/endshort', 'svg');
|
||||
BlockSpecs.redEndH = BlockSpecs.getImageFrom('assets/blocks/eh/stopH');
|
||||
|
||||
BlockSpecs.orangeCmd = BlockSpecs.getImageFrom('assets/blocks/flow', 'svg');
|
||||
BlockSpecs.orangeCmdH = BlockSpecs.getImageFrom('assets/blocks/eh/flowH');
|
||||
|
||||
BlockSpecs.limeCmd = BlockSpecs.getImageFrom('assets/blocks/sounds', 'svg');
|
||||
BlockSpecs.limeCmdH = BlockSpecs.getImageFrom('assets/blocks/eh/soundsH');
|
||||
|
||||
BlockSpecs.pinkCmd = BlockSpecs.getImageFrom('assets/blocks/looks', 'svg');
|
||||
BlockSpecs.pinkCmdH = BlockSpecs.getImageFrom('assets/blocks/eh/looksH');
|
||||
|
||||
BlockSpecs.redEndLong = BlockSpecs.getImageFrom('assets/blocks/endlong', 'svg');
|
||||
BlockSpecs.redEndLongH = BlockSpecs.getImageFrom('assets/blocks/eh/stoplongH');
|
||||
|
||||
BlockSpecs.cShape = BlockSpecs.getImageFrom('assets/blocks/repeat');
|
||||
BlockSpecs.cShapeH = BlockSpecs.getImageFrom('assets/blocks/eh/repeatH');
|
||||
|
||||
BlockSpecs.blueCmd = BlockSpecs.getImageFrom('assets/blocks/blueCmd', 'svg');
|
||||
BlockSpecs.blueCmdH = BlockSpecs.getImageFrom('assets/blocks/eh/blueCmdH');
|
||||
|
||||
BlockSpecs.textfieldimg = BlockSpecs.getImageFrom('assets/misc/Text-01');
|
||||
BlockSpecs.numfieldimg = BlockSpecs.getImageFrom('assets/misc/Number-01');
|
||||
BlockSpecs.pressbutton = BlockSpecs.getImageFrom('assets/misc/pushbutton-01', 'svg');
|
||||
BlockSpecs.pressbuttonSmall = BlockSpecs.getImageFrom('assets/misc/pushbutton', 'svg');
|
||||
BlockSpecs.caretrepeat = BlockSpecs.getImageFrom('assets/blocks/caretrepeat');
|
||||
BlockSpecs.cmdS = BlockSpecs.getImageFrom('assets/blocks/shadowCmd', 'svg');
|
||||
BlockSpecs.startS = BlockSpecs.getImageFrom('assets/blocks/shadowStart', 'svg');
|
||||
BlockSpecs.endS = BlockSpecs.getImageFrom('assets/blocks/shadowEndShort', 'svg');
|
||||
BlockSpecs.endLongS = BlockSpecs.getImageFrom('assets/blocks/shadowEndLong', 'svg');
|
||||
BlockSpecs.repeatS = BlockSpecs.getImageFrom('assets/blocks/shadowRepeat');
|
||||
|
||||
};
|
||||
|
||||
BlockSpecs.getImageFrom = function (url, ext) {
|
||||
var img = document.createElement('img');
|
||||
img.src = url + (ext ? '.' + ext : '.png');
|
||||
if (!img.complete) {
|
||||
BlockSpecs.loadassets[img.src] = img;
|
||||
BlockSpecs.loadCount++;
|
||||
img.onload = function () {
|
||||
delete BlockSpecs.loadassets[img.src];
|
||||
BlockSpecs.loadCount--;
|
||||
};
|
||||
static get fontcolors () {
|
||||
return fontcolors;
|
||||
}
|
||||
|
||||
static get fontsizes () {
|
||||
return fontsizes;
|
||||
}
|
||||
|
||||
static get speeds () {
|
||||
return speeds;
|
||||
}
|
||||
|
||||
static initBlocks () {
|
||||
loadassets = new Object();
|
||||
BlockSpecs.loadGraphics();
|
||||
BlockSpecs.defs = BlockSpecs.setupBlocksSpecs();
|
||||
BlockSpecs.palettes = BlockSpecs.setupPalettesDef();
|
||||
BlockSpecs.categories = BlockSpecs.setupCategories();
|
||||
if (Settings.edition == 'PBS') {
|
||||
BlockSpecs.canvasMask = BlockSpecs.getImageFrom('assets/ui/canvasmask', 'svg');
|
||||
} else {
|
||||
BlockSpecs.canvasMask = BlockSpecs.getImageFrom('assets/ui/canvasmask');
|
||||
}
|
||||
if (Settings.edition != 'PBS') {
|
||||
BlockSpecs.projectThumb = BlockSpecs.getImageFrom('assets/lobby/pmask');
|
||||
}
|
||||
IO.requestFromServer('assets/balloon.svg', BlockSpecs.setBalloon);
|
||||
loadCount++;
|
||||
}
|
||||
|
||||
static setBalloon (str) {
|
||||
loadCount--;
|
||||
BlockSpecs.balloon = str;
|
||||
}
|
||||
return img;
|
||||
};
|
||||
|
||||
|
||||
BlockSpecs.refreshLoading = function () {
|
||||
for (var key in BlockSpecs.loadassets) {
|
||||
if (BlockSpecs.loadassets[key].complete) {
|
||||
BlockSpecs.loadCount--;
|
||||
static loadGraphics () {
|
||||
BlockSpecs.mic = BlockSpecs.getImageFrom('assets/ui/recordslot', 'svg');
|
||||
BlockSpecs.yellowStart = BlockSpecs.getImageFrom('assets/blocks/start', 'svg');
|
||||
BlockSpecs.yellowStartH = BlockSpecs.getImageFrom('assets/blocks/eh/startH');
|
||||
|
||||
BlockSpecs.yellowCmd = BlockSpecs.getImageFrom('assets/blocks/yellowCmd', 'svg');
|
||||
BlockSpecs.yellowCmdH = BlockSpecs.getImageFrom('assets/blocks/eh/yellowCmdH');
|
||||
|
||||
BlockSpecs.redEnd = BlockSpecs.getImageFrom('assets/blocks/endshort', 'svg');
|
||||
BlockSpecs.redEndH = BlockSpecs.getImageFrom('assets/blocks/eh/stopH');
|
||||
|
||||
BlockSpecs.orangeCmd = BlockSpecs.getImageFrom('assets/blocks/flow', 'svg');
|
||||
BlockSpecs.orangeCmdH = BlockSpecs.getImageFrom('assets/blocks/eh/flowH');
|
||||
|
||||
BlockSpecs.limeCmd = BlockSpecs.getImageFrom('assets/blocks/sounds', 'svg');
|
||||
BlockSpecs.limeCmdH = BlockSpecs.getImageFrom('assets/blocks/eh/soundsH');
|
||||
|
||||
BlockSpecs.pinkCmd = BlockSpecs.getImageFrom('assets/blocks/looks', 'svg');
|
||||
BlockSpecs.pinkCmdH = BlockSpecs.getImageFrom('assets/blocks/eh/looksH');
|
||||
|
||||
BlockSpecs.redEndLong = BlockSpecs.getImageFrom('assets/blocks/endlong', 'svg');
|
||||
BlockSpecs.redEndLongH = BlockSpecs.getImageFrom('assets/blocks/eh/stoplongH');
|
||||
|
||||
BlockSpecs.cShape = BlockSpecs.getImageFrom('assets/blocks/repeat');
|
||||
BlockSpecs.cShapeH = BlockSpecs.getImageFrom('assets/blocks/eh/repeatH');
|
||||
|
||||
BlockSpecs.blueCmd = BlockSpecs.getImageFrom('assets/blocks/blueCmd', 'svg');
|
||||
BlockSpecs.blueCmdH = BlockSpecs.getImageFrom('assets/blocks/eh/blueCmdH');
|
||||
|
||||
BlockSpecs.textfieldimg = BlockSpecs.getImageFrom('assets/misc/Text-01');
|
||||
BlockSpecs.numfieldimg = BlockSpecs.getImageFrom('assets/misc/Number-01');
|
||||
BlockSpecs.pressbutton = BlockSpecs.getImageFrom('assets/misc/pushbutton-01', 'svg');
|
||||
BlockSpecs.pressbuttonSmall = BlockSpecs.getImageFrom('assets/misc/pushbutton', 'svg');
|
||||
BlockSpecs.caretrepeat = BlockSpecs.getImageFrom('assets/blocks/caretrepeat');
|
||||
BlockSpecs.cmdS = BlockSpecs.getImageFrom('assets/blocks/shadowCmd', 'svg');
|
||||
BlockSpecs.startS = BlockSpecs.getImageFrom('assets/blocks/shadowStart', 'svg');
|
||||
BlockSpecs.endS = BlockSpecs.getImageFrom('assets/blocks/shadowEndShort', 'svg');
|
||||
BlockSpecs.endLongS = BlockSpecs.getImageFrom('assets/blocks/shadowEndLong', 'svg');
|
||||
BlockSpecs.repeatS = BlockSpecs.getImageFrom('assets/blocks/shadowRepeat');
|
||||
|
||||
}
|
||||
|
||||
static getImageFrom (url, ext) {
|
||||
var img = document.createElement('img');
|
||||
img.src = url + (ext ? '.' + ext : '.png');
|
||||
if (!img.complete) {
|
||||
loadassets[img.src] = img;
|
||||
loadCount++;
|
||||
img.onload = function () {
|
||||
delete loadassets[img.src];
|
||||
loadCount--;
|
||||
};
|
||||
}
|
||||
return img;
|
||||
}
|
||||
|
||||
|
||||
static refreshLoading () {
|
||||
for (var key in loadassets) {
|
||||
if (loadassets[key].complete) {
|
||||
loadCount--;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
BlockSpecs.setupCategories = function () {
|
||||
return new Array(
|
||||
[
|
||||
BlockSpecs.getImageFrom('assets/categories/StartOn', 'svg'),
|
||||
BlockSpecs.getImageFrom('assets/categories/StartOff', 'svg'),
|
||||
Settings.categoryStartColor
|
||||
],
|
||||
[
|
||||
BlockSpecs.getImageFrom('assets/categories/MotionOn', 'svg'),
|
||||
BlockSpecs.getImageFrom('assets/categories/MotionOff', 'svg'),
|
||||
Settings.categoryMotionColor
|
||||
],
|
||||
[
|
||||
BlockSpecs.getImageFrom('assets/categories/LooksOn', 'svg'),
|
||||
BlockSpecs.getImageFrom('assets/categories/LooksOff', 'svg'),
|
||||
Settings.categoryLooksColor
|
||||
],
|
||||
[
|
||||
BlockSpecs.getImageFrom('assets/categories/SoundOn', 'svg'),
|
||||
BlockSpecs.getImageFrom('assets/categories/SoundOff', 'svg'),
|
||||
Settings.categorySoundColor
|
||||
],
|
||||
[
|
||||
BlockSpecs.getImageFrom('assets/categories/FlowOn', 'svg'),
|
||||
BlockSpecs.getImageFrom('assets/categories/FlowOff', 'svg'),
|
||||
Settings.categoryFlowColor
|
||||
],
|
||||
[
|
||||
BlockSpecs.getImageFrom('assets/categories/StopOn', 'svg'),
|
||||
BlockSpecs.getImageFrom('assets/categories/StopOff', 'svg'),
|
||||
Settings.categoryStopColor
|
||||
]
|
||||
);
|
||||
};
|
||||
static setupCategories () {
|
||||
return new Array(
|
||||
[
|
||||
BlockSpecs.getImageFrom('assets/categories/StartOn', 'svg'),
|
||||
BlockSpecs.getImageFrom('assets/categories/StartOff', 'svg'),
|
||||
Settings.categoryStartColor
|
||||
],
|
||||
[
|
||||
BlockSpecs.getImageFrom('assets/categories/MotionOn', 'svg'),
|
||||
BlockSpecs.getImageFrom('assets/categories/MotionOff', 'svg'),
|
||||
Settings.categoryMotionColor
|
||||
],
|
||||
[
|
||||
BlockSpecs.getImageFrom('assets/categories/LooksOn', 'svg'),
|
||||
BlockSpecs.getImageFrom('assets/categories/LooksOff', 'svg'),
|
||||
Settings.categoryLooksColor
|
||||
],
|
||||
[
|
||||
BlockSpecs.getImageFrom('assets/categories/SoundOn', 'svg'),
|
||||
BlockSpecs.getImageFrom('assets/categories/SoundOff', 'svg'),
|
||||
Settings.categorySoundColor
|
||||
],
|
||||
[
|
||||
BlockSpecs.getImageFrom('assets/categories/FlowOn', 'svg'),
|
||||
BlockSpecs.getImageFrom('assets/categories/FlowOff', 'svg'),
|
||||
Settings.categoryFlowColor
|
||||
],
|
||||
[
|
||||
BlockSpecs.getImageFrom('assets/categories/StopOn', 'svg'),
|
||||
BlockSpecs.getImageFrom('assets/categories/StopOff', 'svg'),
|
||||
Settings.categoryStopColor
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
BlockSpecs.setupPalettesDef = function () {
|
||||
return [['onflag', 'onclick', 'ontouch', 'onmessage', 'message'],
|
||||
['forward', 'back', 'up', 'down', 'right', 'left', 'hop', 'home'],
|
||||
['say', 'space', 'grow', 'shrink', 'same', 'space', 'hide', 'show'],
|
||||
[],
|
||||
['wait', 'stopmine', 'setspeed', 'repeat'],
|
||||
['endstack', 'forever']];
|
||||
};
|
||||
static setupPalettesDef () {
|
||||
return [['onflag', 'onclick', 'ontouch', 'onmessage', 'message'],
|
||||
['forward', 'back', 'up', 'down', 'right', 'left', 'hop', 'home'],
|
||||
['say', 'space', 'grow', 'shrink', 'same', 'space', 'hide', 'show'],
|
||||
[],
|
||||
['wait', 'stopmine', 'setspeed', 'repeat'],
|
||||
['endstack', 'forever']];
|
||||
}
|
||||
|
||||
///////////////////////////////
|
||||
// Data Structure
|
||||
//
|
||||
// name - blocktype, icon or datastructure, blockshape, argtype, initial value, highlight, min, max, shadow
|
||||
//
|
||||
// arg types:
|
||||
// null
|
||||
// n -> number field;
|
||||
// t -> text field
|
||||
// m --> image menu with argvalue equal to name;
|
||||
// d --> image menu with argvalue equal to number;
|
||||
// c -- > color drop down
|
||||
// s --> sound name
|
||||
// p --> page icon
|
||||
//
|
||||
////////////////////////////////
|
||||
///////////////////////////////
|
||||
// Data Structure
|
||||
//
|
||||
// name - blocktype, icon or datastructure, blockshape, argtype, initial value, highlight, min, max, shadow
|
||||
//
|
||||
// arg types:
|
||||
// null
|
||||
// n -> number field;
|
||||
// t -> text field
|
||||
// m --> image menu with argvalue equal to name;
|
||||
// d --> image menu with argvalue equal to number;
|
||||
// c -- > color drop down
|
||||
// s --> sound name
|
||||
// p --> page icon
|
||||
//
|
||||
////////////////////////////////
|
||||
|
||||
BlockSpecs.setupBlocksSpecs = function () {
|
||||
return {
|
||||
'onflag': ['onflag', BlockSpecs.getImageFrom('assets/blockicons/greenFlag', 'svg'),
|
||||
BlockSpecs.yellowStart, null, null, BlockSpecs.yellowStartH, null, null, BlockSpecs.startS],
|
||||
'onmessage': ['onmessage', BlockSpecs.getshapes, BlockSpecs.yellowStart, 'm', 'Orange',
|
||||
BlockSpecs.yellowStartH, null, null, BlockSpecs.startS],
|
||||
'onclick': ['onclick', BlockSpecs.getImageFrom('assets/blockicons/OnTouch', 'svg'),
|
||||
BlockSpecs.yellowStart, null, null, BlockSpecs.yellowStartH, null, null, BlockSpecs.startS],
|
||||
'ontouch': ['ontouch', BlockSpecs.getImageFrom('assets/blockicons/Bump', 'svg'),
|
||||
BlockSpecs.yellowStart, null, null, BlockSpecs.yellowStartH, null, null, BlockSpecs.startS],
|
||||
'message': ['message', BlockSpecs.sendshapes, BlockSpecs.yellowCmd, 'm', 'Orange',
|
||||
BlockSpecs.yellowCmdH, null, null, BlockSpecs.cmdS],
|
||||
static setupBlocksSpecs () {
|
||||
return {
|
||||
'onflag': ['onflag', BlockSpecs.getImageFrom('assets/blockicons/greenFlag', 'svg'),
|
||||
BlockSpecs.yellowStart, null, null, BlockSpecs.yellowStartH, null, null, BlockSpecs.startS],
|
||||
'onmessage': ['onmessage', getshapes, BlockSpecs.yellowStart, 'm', 'Orange',
|
||||
BlockSpecs.yellowStartH, null, null, BlockSpecs.startS],
|
||||
'onclick': ['onclick', BlockSpecs.getImageFrom('assets/blockicons/OnTouch', 'svg'),
|
||||
BlockSpecs.yellowStart, null, null, BlockSpecs.yellowStartH, null, null, BlockSpecs.startS],
|
||||
'ontouch': ['ontouch', BlockSpecs.getImageFrom('assets/blockicons/Bump', 'svg'),
|
||||
BlockSpecs.yellowStart, null, null, BlockSpecs.yellowStartH, null, null, BlockSpecs.startS],
|
||||
'message': ['message', sendshapes, BlockSpecs.yellowCmd, 'm', 'Orange',
|
||||
BlockSpecs.yellowCmdH, null, null, BlockSpecs.cmdS],
|
||||
|
||||
'repeat': ['repeat', BlockSpecs.getImageFrom('assets/blockicons/Repeat', 'svg'),
|
||||
BlockSpecs.cShape, 'n', 4, BlockSpecs.cShapeH, 0, 24, BlockSpecs.repeatS],
|
||||
'repeat': ['repeat', BlockSpecs.getImageFrom('assets/blockicons/Repeat', 'svg'),
|
||||
BlockSpecs.cShape, 'n', 4, BlockSpecs.cShapeH, 0, 24, BlockSpecs.repeatS],
|
||||
|
||||
'forward': ['forward', BlockSpecs.getImageFrom('assets/blockicons/Foward', 'svg'),
|
||||
BlockSpecs.blueCmd, 'n', 1, BlockSpecs.blueCmdH, -20, 20, BlockSpecs.cmdS],
|
||||
'back': ['back', BlockSpecs.getImageFrom('assets/blockicons/Back', 'svg'),
|
||||
BlockSpecs.blueCmd, 'n', 1, BlockSpecs.blueCmdH, -20, 20, BlockSpecs.cmdS],
|
||||
'up': ['up', BlockSpecs.getImageFrom('assets/blockicons/Up', 'svg'),
|
||||
BlockSpecs.blueCmd, 'n', 1, BlockSpecs.blueCmdH, -15, 15, BlockSpecs.cmdS],
|
||||
'down': ['down', BlockSpecs.getImageFrom('assets/blockicons/Down', 'svg'),
|
||||
BlockSpecs.blueCmd, 'n', 1, BlockSpecs.blueCmdH, -15, 15, BlockSpecs.cmdS],
|
||||
'right': ['right', BlockSpecs.getImageFrom('assets/blockicons/Right', 'svg'),
|
||||
BlockSpecs.blueCmd, 'n', 1, BlockSpecs.blueCmdH, -12, 12, BlockSpecs.cmdS],
|
||||
'left': ['left', BlockSpecs.getImageFrom('assets/blockicons/Left', 'svg'),
|
||||
BlockSpecs.blueCmd, 'n', 1, BlockSpecs.blueCmdH, -12, 12, BlockSpecs.cmdS],
|
||||
'home': ['home', BlockSpecs.getImageFrom('assets/blockicons/Home', 'svg'),
|
||||
BlockSpecs.blueCmd, null, null, BlockSpecs.blueCmdH, null, null, BlockSpecs.cmdS],
|
||||
'hop': ['hop', BlockSpecs.getImageFrom('assets/blockicons/Hop', 'svg'),
|
||||
BlockSpecs.blueCmd, 'n', 2, BlockSpecs.blueCmdH, -15, 15, BlockSpecs.cmdS],
|
||||
'forward': ['forward', BlockSpecs.getImageFrom('assets/blockicons/Foward', 'svg'),
|
||||
BlockSpecs.blueCmd, 'n', 1, BlockSpecs.blueCmdH, -20, 20, BlockSpecs.cmdS],
|
||||
'back': ['back', BlockSpecs.getImageFrom('assets/blockicons/Back', 'svg'),
|
||||
BlockSpecs.blueCmd, 'n', 1, BlockSpecs.blueCmdH, -20, 20, BlockSpecs.cmdS],
|
||||
'up': ['up', BlockSpecs.getImageFrom('assets/blockicons/Up', 'svg'),
|
||||
BlockSpecs.blueCmd, 'n', 1, BlockSpecs.blueCmdH, -15, 15, BlockSpecs.cmdS],
|
||||
'down': ['down', BlockSpecs.getImageFrom('assets/blockicons/Down', 'svg'),
|
||||
BlockSpecs.blueCmd, 'n', 1, BlockSpecs.blueCmdH, -15, 15, BlockSpecs.cmdS],
|
||||
'right': ['right', BlockSpecs.getImageFrom('assets/blockicons/Right', 'svg'),
|
||||
BlockSpecs.blueCmd, 'n', 1, BlockSpecs.blueCmdH, -12, 12, BlockSpecs.cmdS],
|
||||
'left': ['left', BlockSpecs.getImageFrom('assets/blockicons/Left', 'svg'),
|
||||
BlockSpecs.blueCmd, 'n', 1, BlockSpecs.blueCmdH, -12, 12, BlockSpecs.cmdS],
|
||||
'home': ['home', BlockSpecs.getImageFrom('assets/blockicons/Home', 'svg'),
|
||||
BlockSpecs.blueCmd, null, null, BlockSpecs.blueCmdH, null, null, BlockSpecs.cmdS],
|
||||
'hop': ['hop', BlockSpecs.getImageFrom('assets/blockicons/Hop', 'svg'),
|
||||
BlockSpecs.blueCmd, 'n', 2, BlockSpecs.blueCmdH, -15, 15, BlockSpecs.cmdS],
|
||||
|
||||
|
||||
'wait': ['wait', BlockSpecs.getImageFrom('assets/blockicons/Wait', 'svg'),
|
||||
BlockSpecs.orangeCmd, 'n', 10, BlockSpecs.orangeCmdH, 0, 50, BlockSpecs.cmdS],
|
||||
'setspeed': ['setspeed', BlockSpecs.speeds, BlockSpecs.orangeCmd, 'd', 1,
|
||||
BlockSpecs.orangeCmdH, null, null, BlockSpecs.cmdS],
|
||||
'stopmine': ['stopmine', BlockSpecs.getImageFrom('assets/blockicons/Stop', 'svg'),
|
||||
BlockSpecs.orangeCmd, null, null, BlockSpecs.orangeCmdH, null, null, BlockSpecs.cmdS],
|
||||
'wait': ['wait', BlockSpecs.getImageFrom('assets/blockicons/Wait', 'svg'),
|
||||
BlockSpecs.orangeCmd, 'n', 10, BlockSpecs.orangeCmdH, 0, 50, BlockSpecs.cmdS],
|
||||
'setspeed': ['setspeed', speeds, BlockSpecs.orangeCmd, 'd', 1,
|
||||
BlockSpecs.orangeCmdH, null, null, BlockSpecs.cmdS],
|
||||
'stopmine': ['stopmine', BlockSpecs.getImageFrom('assets/blockicons/Stop', 'svg'),
|
||||
BlockSpecs.orangeCmd, null, null, BlockSpecs.orangeCmdH, null, null, BlockSpecs.cmdS],
|
||||
|
||||
'say': ['say', BlockSpecs.getImageFrom('assets/blockicons/Say', 'svg'),
|
||||
BlockSpecs.pinkCmd, 't',
|
||||
Localization.localize('SAY_BLOCK_DEFAULT_ARGUMENT'), BlockSpecs.pinkCmdH, null, null, BlockSpecs.cmdS],
|
||||
'show': ['show', BlockSpecs.getImageFrom('assets/blockicons/Appear', 'svg'),
|
||||
BlockSpecs.pinkCmd, null, null, BlockSpecs.pinkCmdH, null, null, BlockSpecs.cmdS],
|
||||
'hide': ['hide', BlockSpecs.getImageFrom('assets/blockicons/Disappear', 'svg'),
|
||||
BlockSpecs.pinkCmd, null, null, BlockSpecs.pinkCmdH, null, null, BlockSpecs.cmdS],
|
||||
'grow': ['grow', BlockSpecs.getImageFrom('assets/blockicons/Grow', 'svg'),
|
||||
BlockSpecs.pinkCmd, 'n', 2, BlockSpecs.pinkCmdH, -10, 10, BlockSpecs.cmdS],
|
||||
'shrink': ['shrink', BlockSpecs.getImageFrom('assets/blockicons/Shrink', 'svg'),
|
||||
BlockSpecs.pinkCmd, 'n', 2, BlockSpecs.pinkCmdH, -10, 10, BlockSpecs.cmdS],
|
||||
'same': ['same', BlockSpecs.getImageFrom('assets/blockicons/Reset', 'svg'),
|
||||
BlockSpecs.pinkCmd, null, null, BlockSpecs.pinkCmdH, null, null, BlockSpecs.cmdS],
|
||||
'say': ['say', BlockSpecs.getImageFrom('assets/blockicons/Say', 'svg'),
|
||||
BlockSpecs.pinkCmd, 't',
|
||||
Localization.localize('SAY_BLOCK_DEFAULT_ARGUMENT'), BlockSpecs.pinkCmdH, null, null, BlockSpecs.cmdS],
|
||||
'show': ['show', BlockSpecs.getImageFrom('assets/blockicons/Appear', 'svg'),
|
||||
BlockSpecs.pinkCmd, null, null, BlockSpecs.pinkCmdH, null, null, BlockSpecs.cmdS],
|
||||
'hide': ['hide', BlockSpecs.getImageFrom('assets/blockicons/Disappear', 'svg'),
|
||||
BlockSpecs.pinkCmd, null, null, BlockSpecs.pinkCmdH, null, null, BlockSpecs.cmdS],
|
||||
'grow': ['grow', BlockSpecs.getImageFrom('assets/blockicons/Grow', 'svg'),
|
||||
BlockSpecs.pinkCmd, 'n', 2, BlockSpecs.pinkCmdH, -10, 10, BlockSpecs.cmdS],
|
||||
'shrink': ['shrink', BlockSpecs.getImageFrom('assets/blockicons/Shrink', 'svg'),
|
||||
BlockSpecs.pinkCmd, 'n', 2, BlockSpecs.pinkCmdH, -10, 10, BlockSpecs.cmdS],
|
||||
'same': ['same', BlockSpecs.getImageFrom('assets/blockicons/Reset', 'svg'),
|
||||
BlockSpecs.pinkCmd, null, null, BlockSpecs.pinkCmdH, null, null, BlockSpecs.cmdS],
|
||||
|
||||
'playsnd': ['playsnd', BlockSpecs.getImageFrom('assets/blockicons/Speaker', 'svg'),
|
||||
BlockSpecs.limeCmd, 's', 'pop.mp3', BlockSpecs.limeCmdH, null, null, BlockSpecs.cmdS],
|
||||
'playusersnd': ['playusersnd', BlockSpecs.getImageFrom('assets/blockicons/Microphone', 'svg'),
|
||||
BlockSpecs.limeCmd, 'r', '1', BlockSpecs.limeCmdH, null, null, BlockSpecs.cmdS],
|
||||
'endstack': ['endstack', null, BlockSpecs.redEnd, null, null, BlockSpecs.redEndH, null, null, BlockSpecs.endS],
|
||||
'forever': ['forever', BlockSpecs.getImageFrom('assets/blockicons/Forever', 'svg'),
|
||||
BlockSpecs.redEnd, null, null, BlockSpecs.redEndH, null, null, BlockSpecs.endS],
|
||||
'gotopage': ['gotopage', null,
|
||||
BlockSpecs.redEndLong, 'p', '2', BlockSpecs.redEndLongH, null, null, BlockSpecs.endLongS],
|
||||
'caretstart': ['caretstart', null,
|
||||
BlockSpecs.getImageFrom('assets/blocks/caretstart', 'svg'), null, null, null, null, null],
|
||||
'caretend': ['caretend', null,
|
||||
BlockSpecs.getImageFrom('assets/blocks/caretend', 'svg'), null, null, null, null, null],
|
||||
'caretrepeat': ['caretrepeat', null,
|
||||
BlockSpecs.getImageFrom('assets/blocks/caretrepeat'), null, null, null, null, null],
|
||||
'caretcmd': ['caretcmd', null,
|
||||
BlockSpecs.getImageFrom('assets/blocks/caretcmd', 'svg'), null, null, null, null, null]
|
||||
'playsnd': ['playsnd', BlockSpecs.getImageFrom('assets/blockicons/Speaker', 'svg'),
|
||||
BlockSpecs.limeCmd, 's', 'pop.mp3', BlockSpecs.limeCmdH, null, null, BlockSpecs.cmdS],
|
||||
'playusersnd': ['playusersnd', BlockSpecs.getImageFrom('assets/blockicons/Microphone', 'svg'),
|
||||
BlockSpecs.limeCmd, 'r', '1', BlockSpecs.limeCmdH, null, null, BlockSpecs.cmdS],
|
||||
'endstack': ['endstack', null, BlockSpecs.redEnd, null, null,
|
||||
BlockSpecs.redEndH, null, null, BlockSpecs.endS],
|
||||
'forever': ['forever', BlockSpecs.getImageFrom('assets/blockicons/Forever', 'svg'),
|
||||
BlockSpecs.redEnd, null, null, BlockSpecs.redEndH, null, null, BlockSpecs.endS],
|
||||
'gotopage': ['gotopage', null,
|
||||
BlockSpecs.redEndLong, 'p', '2', BlockSpecs.redEndLongH, null, null, BlockSpecs.endLongS],
|
||||
'caretstart': ['caretstart', null,
|
||||
BlockSpecs.getImageFrom('assets/blocks/caretstart', 'svg'), null, null, null, null, null],
|
||||
'caretend': ['caretend', null,
|
||||
BlockSpecs.getImageFrom('assets/blocks/caretend', 'svg'), null, null, null, null, null],
|
||||
'caretrepeat': ['caretrepeat', null,
|
||||
BlockSpecs.getImageFrom('assets/blocks/caretrepeat'), null, null, null, null, null],
|
||||
'caretcmd': ['caretcmd', null,
|
||||
BlockSpecs.getImageFrom('assets/blocks/caretcmd', 'svg'), null, null, null, null, null]
|
||||
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
BlockSpecs.blockDesc = function (b, spr) {
|
||||
var str = b.getArgValue() ? b.getArgValue().toString() : (b.blocktype == 'playsnd') ? 'SOUND' : '';
|
||||
static blockDesc (b, spr) {
|
||||
var str = b.getArgValue() ? b.getArgValue().toString() : (b.blocktype == 'playsnd') ? 'SOUND' : '';
|
||||
|
||||
return {
|
||||
'onflag': Localization.localize('BLOCK_DESC_GREEN_FLAG'),
|
||||
'onclick': Localization.localize('BLOCK_DESC_ON_TAP', {
|
||||
CHARACTER_NAME: spr.name
|
||||
}),
|
||||
'ontouch': Localization.localize('BLOCK_DESC_ON_BUMP', {
|
||||
CHARACTER_NAME: spr.name ? spr.name : ''
|
||||
}),
|
||||
'onmessage': Localization.localize('BLOCK_DESC_ON_MESSAGE', {
|
||||
COLOR: Localization.localize('BLOCK_DESC_MESSAGE_COLOR_ORANGE')
|
||||
}),
|
||||
'repeat': Localization.localize('BLOCK_DESC_REPEAT'),
|
||||
'forward': Localization.localize('BLOCK_DESC_MOVE_RIGHT'),
|
||||
'back': Localization.localize('BLOCK_DESC_MOVE_LEFT'),
|
||||
'up': Localization.localize('BLOCK_DESC_MOVE_UP'),
|
||||
'down': Localization.localize('BLOCK_DESC_MOVE_DOWN'),
|
||||
'home': Localization.localize('BLOCK_DESC_GO_HOME'),
|
||||
'left': Localization.localize('BLOCK_DESC_TURN_LEFT'),
|
||||
'right': Localization.localize('BLOCK_DESC_TURN_RIGHT'),
|
||||
'hop': Localization.localize('BLOCK_DESC_HOP'),
|
||||
'wait': Localization.localize('BLOCK_DESC_WAIT'),
|
||||
'setspeed': Localization.localize('BLOCK_DESC_SET_SPEED'),
|
||||
'stopmine': Localization.localize('BLOCK_DESC_STOP', {
|
||||
CHARACTER_NAME: spr.name ? spr.name : spr.str
|
||||
}),
|
||||
'say': Localization.localize('BLOCK_DESC_SAY'),
|
||||
'show': Localization.localize('BLOCK_DESC_SHOW'),
|
||||
'hide': Localization.localize('BLOCK_DESC_HIDE'),
|
||||
'grow': Localization.localize('BLOCK_DESC_GROW'),
|
||||
'shrink': Localization.localize('BLOCK_DESC_SHRINK'),
|
||||
'same': Localization.localize('BLOCK_DESC_RESET_SIZE'),
|
||||
'playsnd': Localization.localize('BLOCK_DESC_PLAY_SOUND', {
|
||||
SOUND_NAME: Localization.localize('BLOCK_DESC_PLAY_SOUND_POP')
|
||||
}),
|
||||
'playusersnd': Localization.localize('BLOCK_DESC_PLAY_RECORDED_SOUND'),
|
||||
'endstack': Localization.localize('BLOCK_DESC_END'),
|
||||
'stopall': Localization.localize('BLOCK_DESC_STOP', {
|
||||
CHARACTER_NAME: spr.name ? spr.name : ''
|
||||
}),
|
||||
'forever': Localization.localize('BLOCK_DESC_REPEAT_FOREVER'),
|
||||
'gotopage': Localization.localize('BLOCK_DESC_GO_TO_PAGE', {
|
||||
PAGE: str
|
||||
}),
|
||||
'message': Localization.localize('BLOCK_DESC_SEND_MESSAGE', {
|
||||
COLOR: Localization.localize('BLOCK_DESC_MESSAGE_COLOR_ORANGE')
|
||||
})
|
||||
};
|
||||
};
|
||||
return {
|
||||
'onflag': Localization.localize('BLOCK_DESC_GREEN_FLAG'),
|
||||
'onclick': Localization.localize('BLOCK_DESC_ON_TAP', {
|
||||
CHARACTER_NAME: spr.name
|
||||
}),
|
||||
'ontouch': Localization.localize('BLOCK_DESC_ON_BUMP', {
|
||||
CHARACTER_NAME: spr.name ? spr.name : ''
|
||||
}),
|
||||
'onmessage': Localization.localize('BLOCK_DESC_ON_MESSAGE', {
|
||||
COLOR: Localization.localize('BLOCK_DESC_MESSAGE_COLOR_ORANGE')
|
||||
}),
|
||||
'repeat': Localization.localize('BLOCK_DESC_REPEAT'),
|
||||
'forward': Localization.localize('BLOCK_DESC_MOVE_RIGHT'),
|
||||
'back': Localization.localize('BLOCK_DESC_MOVE_LEFT'),
|
||||
'up': Localization.localize('BLOCK_DESC_MOVE_UP'),
|
||||
'down': Localization.localize('BLOCK_DESC_MOVE_DOWN'),
|
||||
'home': Localization.localize('BLOCK_DESC_GO_HOME'),
|
||||
'left': Localization.localize('BLOCK_DESC_TURN_LEFT'),
|
||||
'right': Localization.localize('BLOCK_DESC_TURN_RIGHT'),
|
||||
'hop': Localization.localize('BLOCK_DESC_HOP'),
|
||||
'wait': Localization.localize('BLOCK_DESC_WAIT'),
|
||||
'setspeed': Localization.localize('BLOCK_DESC_SET_SPEED'),
|
||||
'stopmine': Localization.localize('BLOCK_DESC_STOP', {
|
||||
CHARACTER_NAME: spr.name ? spr.name : spr.str
|
||||
}),
|
||||
'say': Localization.localize('BLOCK_DESC_SAY'),
|
||||
'show': Localization.localize('BLOCK_DESC_SHOW'),
|
||||
'hide': Localization.localize('BLOCK_DESC_HIDE'),
|
||||
'grow': Localization.localize('BLOCK_DESC_GROW'),
|
||||
'shrink': Localization.localize('BLOCK_DESC_SHRINK'),
|
||||
'same': Localization.localize('BLOCK_DESC_RESET_SIZE'),
|
||||
'playsnd': Localization.localize('BLOCK_DESC_PLAY_SOUND', {
|
||||
SOUND_NAME: Localization.localize('BLOCK_DESC_PLAY_SOUND_POP')
|
||||
}),
|
||||
'playusersnd': Localization.localize('BLOCK_DESC_PLAY_RECORDED_SOUND'),
|
||||
'endstack': Localization.localize('BLOCK_DESC_END'),
|
||||
'stopall': Localization.localize('BLOCK_DESC_STOP', {
|
||||
CHARACTER_NAME: spr.name ? spr.name : ''
|
||||
}),
|
||||
'forever': Localization.localize('BLOCK_DESC_REPEAT_FOREVER'),
|
||||
'gotopage': Localization.localize('BLOCK_DESC_GO_TO_PAGE', {
|
||||
PAGE: str
|
||||
}),
|
||||
'message': Localization.localize('BLOCK_DESC_SEND_MESSAGE', {
|
||||
COLOR: Localization.localize('BLOCK_DESC_MESSAGE_COLOR_ORANGE')
|
||||
})
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,92 +1,104 @@
|
|||
var Menu = function () {};
|
||||
import BlockSpecs from './BlockSpecs';
|
||||
import {scaleMultiplier, setProps, setCanvasSize, newHTML, isTablet,
|
||||
newDiv, getDocumentHeight, drawThumbnail, frame, globalx, globaly} from '../../utils/lib';
|
||||
|
||||
Menu.openMenu = undefined;
|
||||
let openMenu = undefined;
|
||||
|
||||
Menu.openDropDown = function (b, fcn) {
|
||||
var size = 50;
|
||||
var color = b.owner.blocktype == 'setspeed' ? 'orange' : 'yellow';
|
||||
var list = JSON.parse(b.owner.arg.list);
|
||||
var num = b.owner.arg.numperrow;
|
||||
var p = b.parentNode;
|
||||
var dh = size * Math.round(list.length / num);
|
||||
var rows = list.length / num;
|
||||
var w = size * list.length / rows;
|
||||
var scaledWidth = w * scaleMultiplier;
|
||||
var dx = b.left + (b.offsetWidth - scaledWidth) / 2;
|
||||
if ((dx + scaledWidth) > p.width) {
|
||||
dx -= ((dx + scaledWidth) - p.width);
|
||||
export default class Menu {
|
||||
static get openMenu () {
|
||||
return openMenu;
|
||||
}
|
||||
if (dx < 5) {
|
||||
dx = 5;
|
||||
}
|
||||
dx += globalx(p, 0);
|
||||
var dy = b.top + b.offsetHeight - ((10 + 18) * scaleMultiplier) + globaly(p, 0);
|
||||
if ((dy + ((10 + dh) * scaleMultiplier)) > getDocumentHeight()) {
|
||||
dy = getDocumentHeight() - ((15 + dh) * scaleMultiplier);
|
||||
}
|
||||
var mu = newDiv(frame, dx, dy, w, dh, {
|
||||
position: 'absolute',
|
||||
zIndex: 100000,
|
||||
webkitTransform: 'translate(' + (-w / 2) + 'px,' + (-dh / 2) + 'px) ' +
|
||||
'scale(' + scaleMultiplier + ', ' + scaleMultiplier + ') ' +
|
||||
'translate(' + (w / 2) + 'px, ' + (dh / 2) + 'px)'
|
||||
});
|
||||
mu.setAttribute('class', 'menustyle ' + color);
|
||||
mu.active = b;
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
Menu.addImageToDropDown(mu, list[i], b, fcn);
|
||||
}
|
||||
Menu.openMenu = mu;
|
||||
};
|
||||
|
||||
Menu.addImageToDropDown = function (mu, c, block, fcn) {
|
||||
var img = BlockSpecs.getImageFrom('assets/blockicons/' + c, 'svg');
|
||||
var cs = newHTML('div', 'ddchoice', mu);
|
||||
var micon = newHTML('canvas', undefined, cs);
|
||||
var iconSize = 42;
|
||||
var scaledIconSize = iconSize * window.devicePixelRatio;
|
||||
setCanvasSize(micon, scaledIconSize, scaledIconSize);
|
||||
setProps(micon.style, {
|
||||
webkitTransform: 'translate(' + (-scaledIconSize / 2) + 'px, ' + (-scaledIconSize / 2) + 'px) ' +
|
||||
'scale(' + (1 / window.devicePixelRatio) + ', ' + (1 / window.devicePixelRatio) + ') ' +
|
||||
'translate(' + (scaledIconSize / 2) + 'px, ' + (scaledIconSize / 2) + 'px)'
|
||||
});
|
||||
if (!img.complete) {
|
||||
img.onload = function () {
|
||||
static set openMenu (newOpenMenu) {
|
||||
openMenu = newOpenMenu;
|
||||
}
|
||||
|
||||
static openDropDown (b, fcn) {
|
||||
var size = 50;
|
||||
var color = b.owner.blocktype == 'setspeed' ? 'orange' : 'yellow';
|
||||
var list = JSON.parse(b.owner.arg.list);
|
||||
var num = b.owner.arg.numperrow;
|
||||
var p = b.parentNode;
|
||||
var dh = size * Math.round(list.length / num);
|
||||
var rows = list.length / num;
|
||||
var w = size * list.length / rows;
|
||||
var scaledWidth = w * scaleMultiplier;
|
||||
var dx = b.left + (b.offsetWidth - scaledWidth) / 2;
|
||||
if ((dx + scaledWidth) > p.width) {
|
||||
dx -= ((dx + scaledWidth) - p.width);
|
||||
}
|
||||
if (dx < 5) {
|
||||
dx = 5;
|
||||
}
|
||||
dx += globalx(p, 0);
|
||||
var dy = b.top + b.offsetHeight - ((10 + 18) * scaleMultiplier) + globaly(p, 0);
|
||||
if ((dy + ((10 + dh) * scaleMultiplier)) > getDocumentHeight()) {
|
||||
dy = getDocumentHeight() - ((15 + dh) * scaleMultiplier);
|
||||
}
|
||||
var mu = newDiv(frame, dx, dy, w, dh, {
|
||||
position: 'absolute',
|
||||
zIndex: 100000,
|
||||
webkitTransform: 'translate(' + (-w / 2) + 'px,' + (-dh / 2) + 'px) ' +
|
||||
'scale(' + scaleMultiplier + ', ' + scaleMultiplier + ') ' +
|
||||
'translate(' + (w / 2) + 'px, ' + (dh / 2) + 'px)'
|
||||
});
|
||||
mu.setAttribute('class', 'menustyle ' + color);
|
||||
mu.active = b;
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
Menu.addImageToDropDown(mu, list[i], b, fcn);
|
||||
}
|
||||
openMenu = mu;
|
||||
}
|
||||
|
||||
static addImageToDropDown (mu, c, block, fcn) {
|
||||
var img = BlockSpecs.getImageFrom('assets/blockicons/' + c, 'svg');
|
||||
var cs = newHTML('div', 'ddchoice', mu);
|
||||
var micon = newHTML('canvas', undefined, cs);
|
||||
var iconSize = 42;
|
||||
var scaledIconSize = iconSize * window.devicePixelRatio;
|
||||
setCanvasSize(micon, scaledIconSize, scaledIconSize);
|
||||
setProps(micon.style, {
|
||||
webkitTransform: 'translate(' + (-scaledIconSize / 2) + 'px, ' + (-scaledIconSize / 2) + 'px) ' +
|
||||
'scale(' + (1 / window.devicePixelRatio) + ', ' + (1 / window.devicePixelRatio) + ') ' +
|
||||
'translate(' + (scaledIconSize / 2) + 'px, ' + (scaledIconSize / 2) + 'px)'
|
||||
});
|
||||
if (!img.complete) {
|
||||
img.onload = function () {
|
||||
drawThumbnail(img, micon);
|
||||
};
|
||||
} else {
|
||||
drawThumbnail(img, micon);
|
||||
};
|
||||
} else {
|
||||
drawThumbnail(img, micon);
|
||||
}
|
||||
if (isTablet) {
|
||||
cs.ontouchstart = function (evt) {
|
||||
handleTouchStart(evt);
|
||||
};
|
||||
} else {
|
||||
cs.onmouseover = function (evt) {
|
||||
Menu.highlightdot(evt);
|
||||
};
|
||||
cs.onmouseout = function (evt) {
|
||||
Menu.unhighlightdot(evt);
|
||||
};
|
||||
cs.onmousedown = function (evt) {
|
||||
fcn(evt, mu, block, c);
|
||||
};
|
||||
}
|
||||
function handleTouchStart (e) {
|
||||
if (isTablet && e.touches && (e.touches.length > 1)) {
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
fcn(e, mu, block, c);
|
||||
}
|
||||
}
|
||||
if (isTablet) {
|
||||
cs.ontouchstart = function (evt) {
|
||||
handleTouchStart(evt);
|
||||
};
|
||||
} else {
|
||||
cs.onmouseover = function (evt) {
|
||||
Menu.highlightdot(evt);
|
||||
};
|
||||
cs.onmouseout = function (evt) {
|
||||
Menu.unhighlightdot(evt);
|
||||
};
|
||||
cs.onmousedown = function (evt) {
|
||||
fcn(evt, mu, block, c);
|
||||
};
|
||||
}
|
||||
function handleTouchStart (e) {
|
||||
if (isTablet && e.touches && (e.touches.length > 1)) {
|
||||
|
||||
static closeMyOpenMenu () {
|
||||
if (!openMenu) {
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
fcn(e, mu, block, c);
|
||||
openMenu.parentNode.removeChild(openMenu);
|
||||
openMenu = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
Menu.closeMyOpenMenu = function () {
|
||||
if (!Menu.openMenu) {
|
||||
return;
|
||||
}
|
||||
Menu.openMenu.parentNode.removeChild(Menu.openMenu);
|
||||
Menu.openMenu = undefined;
|
||||
};
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -863,7 +863,6 @@ Sprite.prototype.activateInput = function () {
|
|||
var ti = document.forms.activetextbox.typing;
|
||||
gn('textbox').style.visibility = 'visible';
|
||||
var me = this;
|
||||
Undo.aux = Project.getProject(ScratchJr.stage.currentPage.id);
|
||||
ti.onblur = function () {
|
||||
me.unfocusText();
|
||||
};
|
||||
|
|
|
@ -1,66 +1,74 @@
|
|||
var Alert = function () {};
|
||||
import DrawPath from '../../utils/DrawPath';
|
||||
import {globalx, globaly, scaleMultiplier, newCanvas,
|
||||
setCanvasSize, setProps, writeText, getStringSize} from '../../utils/lib';
|
||||
|
||||
Alert.balloon = undefined;
|
||||
let balloon = undefined;
|
||||
|
||||
Alert.close = function () {
|
||||
if (!Alert.balloon) {
|
||||
return;
|
||||
}
|
||||
Alert.balloon.parentNode.removeChild(Alert.balloon);
|
||||
Alert.balloon = undefined;
|
||||
};
|
||||
|
||||
Alert.open = function (p, obj, label, color) {
|
||||
if (Alert.balloon) {
|
||||
Alert.close();
|
||||
}
|
||||
var scale = scaleMultiplier;
|
||||
var w = 80;
|
||||
var h = 24;
|
||||
var dx = (globalx(obj, obj.offsetLeft) + (obj.offsetWidth / 2)) - (w + 7 * 2 + 4) * scale / 2;
|
||||
var dy = globaly(obj, obj.offsetTop) - (24 * scale);
|
||||
if (dy < 5 * scale) {
|
||||
dy = 5 * scale;
|
||||
export default class Alert {
|
||||
static get balloon () {
|
||||
return balloon;
|
||||
}
|
||||
|
||||
Alert.balloon = newCanvas(p, dx, dy, w, h, {
|
||||
position: 'absolute',
|
||||
zIndex: 2
|
||||
});
|
||||
Alert.balloon.icon = obj;
|
||||
var ctx = Alert.balloon.getContext('2d');
|
||||
w = 16 + getStringSize(ctx, 'bold 14px Verdana', label).width;
|
||||
if (w < 36) {
|
||||
w = 36;
|
||||
static close () {
|
||||
if (!balloon) {
|
||||
return;
|
||||
}
|
||||
balloon.parentNode.removeChild(balloon);
|
||||
balloon = undefined;
|
||||
}
|
||||
dx = (globalx(obj, obj.offsetLeft) + (obj.offsetWidth / 2)) - (w + 7 * 2 + 4) * scale / 2;
|
||||
if (dx < 5 * scale) {
|
||||
dx = 5 * scale;
|
||||
}
|
||||
dx = Math.floor(dx);
|
||||
setCanvasSize(Alert.balloon, w, 36);
|
||||
setProps(Alert.balloon.style, {
|
||||
position: 'absolute',
|
||||
left: dx + 'px',
|
||||
zIndex: 1000,
|
||||
webkitTransform: 'translate(' + (-w / 2) + 'px, ' + (-h / 2) + 'px) ' +
|
||||
'scale(' + scale + ', ' + scale + ') ' +
|
||||
'translate(' + (w / 2) + 'px, ' + (h / 2) + 'px) '
|
||||
});
|
||||
Alert.draw(Alert.balloon.getContext('2d'), 6, w, h, color);
|
||||
writeText(ctx, 'bold 14px Verdana', 'white', label, 20, 8);
|
||||
};
|
||||
|
||||
Alert.draw = function (ctx, curve, w, h, color) {
|
||||
curve = 10;
|
||||
var path = new Array(['M', 0, curve], ['q', 0, -curve, curve, -curve], ['h', w - curve * 2],
|
||||
['q', curve, 0, curve, curve], ['v', h - curve * 2], ['q', 0, curve, -curve, curve],
|
||||
['h', -(w / 2) + 7 + curve], ['l', -7, 7], ['l', -7, -7], ['h', -(w / 2) + 7 + curve],
|
||||
['q', -curve, 0, -curve, -curve], ['Z']
|
||||
);
|
||||
ctx.clearRect(0, 0, Math.max(ctx.canvas.width, w), Math.max(ctx.canvas.height, h));
|
||||
ctx.fillStyle = color;
|
||||
ctx.beginPath();
|
||||
DrawPath.render(ctx, path);
|
||||
ctx.fill();
|
||||
};
|
||||
static open (p, obj, label, color) {
|
||||
if (balloon) {
|
||||
Alert.close();
|
||||
}
|
||||
var scale = scaleMultiplier;
|
||||
var w = 80;
|
||||
var h = 24;
|
||||
var dx = (globalx(obj, obj.offsetLeft) + (obj.offsetWidth / 2)) - (w + 7 * 2 + 4) * scale / 2;
|
||||
var dy = globaly(obj, obj.offsetTop) - (24 * scale);
|
||||
if (dy < 5 * scale) {
|
||||
dy = 5 * scale;
|
||||
}
|
||||
|
||||
balloon = newCanvas(p, dx, dy, w, h, {
|
||||
position: 'absolute',
|
||||
zIndex: 2
|
||||
});
|
||||
balloon.icon = obj;
|
||||
var ctx = balloon.getContext('2d');
|
||||
w = 16 + getStringSize(ctx, 'bold 14px Verdana', label).width;
|
||||
if (w < 36) {
|
||||
w = 36;
|
||||
}
|
||||
dx = (globalx(obj, obj.offsetLeft) + (obj.offsetWidth / 2)) - (w + 7 * 2 + 4) * scale / 2;
|
||||
if (dx < 5 * scale) {
|
||||
dx = 5 * scale;
|
||||
}
|
||||
dx = Math.floor(dx);
|
||||
setCanvasSize(balloon, w, 36);
|
||||
setProps(balloon.style, {
|
||||
position: 'absolute',
|
||||
left: dx + 'px',
|
||||
zIndex: 1000,
|
||||
webkitTransform: 'translate(' + (-w / 2) + 'px, ' + (-h / 2) + 'px) ' +
|
||||
'scale(' + scale + ', ' + scale + ') ' +
|
||||
'translate(' + (w / 2) + 'px, ' + (h / 2) + 'px) '
|
||||
});
|
||||
Alert.draw(balloon.getContext('2d'), 6, w, h, color);
|
||||
writeText(ctx, 'bold 14px Verdana', 'white', label, 20, 8);
|
||||
}
|
||||
|
||||
static draw (ctx, curve, w, h, color) {
|
||||
curve = 10;
|
||||
var path = new Array(['M', 0, curve], ['q', 0, -curve, curve, -curve], ['h', w - curve * 2],
|
||||
['q', curve, 0, curve, curve], ['v', h - curve * 2], ['q', 0, curve, -curve, curve],
|
||||
['h', -(w / 2) + 7 + curve], ['l', -7, 7], ['l', -7, -7], ['h', -(w / 2) + 7 + curve],
|
||||
['q', -curve, 0, -curve, -curve], ['Z']
|
||||
);
|
||||
ctx.clearRect(0, 0, Math.max(ctx.canvas.width, w), Math.max(ctx.canvas.height, h));
|
||||
ctx.fillStyle = color;
|
||||
ctx.beginPath();
|
||||
DrawPath.render(ctx, path);
|
||||
ctx.fill();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,264 +2,276 @@
|
|||
// Stage grid
|
||||
//////////////////////////////
|
||||
|
||||
var Grid = function () {};
|
||||
import ScratchJr from '../ScratchJr';
|
||||
import Events from '../../utils/Events';
|
||||
import Localization from '../../utils/Localization';
|
||||
import {gn, scaleMultiplier, isTablet, newDiv, setProps, newP, newCanvas} from '../../utils/lib';
|
||||
|
||||
Grid.width = 482;
|
||||
Grid.height = 362;
|
||||
Grid.size = 24;
|
||||
let width = 482;
|
||||
let height = 362;
|
||||
let size = 24;
|
||||
let hidden = true;
|
||||
|
||||
Grid.hidden = true;
|
||||
|
||||
Grid.init = function (div) {
|
||||
var w = div.offsetWidth;
|
||||
var h = div.offsetHeight;
|
||||
var grid = newDiv(div, 0, 0, Grid.width, Grid.height, {
|
||||
position: 'absolute',
|
||||
zIndex: ScratchJr.layerTop
|
||||
});
|
||||
Grid.setScaleAndPosition(grid, scaleMultiplier, 47, 75, Grid.width, Grid.height);
|
||||
grid.setAttribute('id', 'livegrid');
|
||||
Grid.drawLines(grid, Grid.width, Grid.height);
|
||||
Grid.createNumbering(w, h);
|
||||
Grid.createCursor();
|
||||
Grid.createYcursor();
|
||||
Grid.createXcursor();
|
||||
};
|
||||
|
||||
Grid.setScaleAndPosition = function (grid, scale, x, y, w, h) {
|
||||
setProps(grid.style, {
|
||||
webkitTransform: 'translate(' + (-w / 2) + 'px, ' + (-h / 2) + 'px) ' +
|
||||
'scale(' + scale + ') ' +
|
||||
'translate(' + (w / 2 + x) + 'px, ' + (h / 2 + y) + 'px)'
|
||||
});
|
||||
};
|
||||
|
||||
Grid.drawLines = function (grid, w, h) {
|
||||
var cnv = newCanvas(grid, 0, 0, w, h, {
|
||||
position: 'absolute'
|
||||
});
|
||||
cnv.style.opacity = 0.5;
|
||||
var ctx = cnv.getContext('2d');
|
||||
ctx.strokeStyle = '#B3B3B3';
|
||||
ctx.lineWidth = 1;
|
||||
var dx = Grid.size;
|
||||
// vertical
|
||||
for (var i = 0; i < 480 / Grid.size; i++) {
|
||||
ctx.moveTo(dx, 0);
|
||||
ctx.lineTo(dx, 360);
|
||||
ctx.stroke();
|
||||
dx += Grid.size;
|
||||
export default class Grid {
|
||||
static get size () {
|
||||
return size;
|
||||
}
|
||||
var dy = Grid.size;
|
||||
// horizontal
|
||||
for (i = 0; i < 360 / Grid.size; i++) {
|
||||
ctx.moveTo(0, dy);
|
||||
ctx.lineTo(480, dy);
|
||||
ctx.stroke();
|
||||
dy += Grid.size;
|
||||
}
|
||||
if (isTablet) {
|
||||
cnv.ontouchstart = function (evt) {
|
||||
ScratchJr.stage.mouseDown(evt);
|
||||
};
|
||||
} else {
|
||||
cnv.onmousedown = function (evt) {
|
||||
ScratchJr.stage.mouseDown(evt);
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
Grid.createNumbering = function (w, h) {
|
||||
var row = newDiv(gn('stageframe'), 0, 0, w - 46 - 30, 24, {
|
||||
position: 'absolute',
|
||||
zIndex: ScratchJr.layerTop
|
||||
});
|
||||
row.setAttribute('id', 'rownum');
|
||||
Grid.setScaleAndPosition(row, scaleMultiplier, 46 - 24, 75 + Grid.height, w - 46 - 30, 24);
|
||||
var offset = Grid.size;
|
||||
var dx = offset;
|
||||
for (var i = 0; i < 480 / offset; i++) {
|
||||
var num = newDiv(row, dx, 0, Grid.size, Grid.size, {
|
||||
static get hidden () {
|
||||
return hidden;
|
||||
}
|
||||
|
||||
static init (div) {
|
||||
var w = div.offsetWidth;
|
||||
var h = div.offsetHeight;
|
||||
var grid = newDiv(div, 0, 0, width, height, {
|
||||
position: 'absolute',
|
||||
zIndex: 10
|
||||
zIndex: ScratchJr.layerTop
|
||||
});
|
||||
var p = newP(num, Localization.localize('GRID_NUMBER', {
|
||||
N: (i + 1)
|
||||
}), {});
|
||||
p.setAttribute('class', 'stylelabel');
|
||||
dx += offset;
|
||||
Grid.setScaleAndPosition(grid, scaleMultiplier, 47, 75, width, height);
|
||||
grid.setAttribute('id', 'livegrid');
|
||||
Grid.drawLines(grid, width, height);
|
||||
Grid.createNumbering(w, h);
|
||||
Grid.createCursor();
|
||||
Grid.createYcursor();
|
||||
Grid.createXcursor();
|
||||
}
|
||||
var column = newDiv(gn('stageframe'), 0, 0, 24, h + 24, {
|
||||
position: 'absolute',
|
||||
zIndex: ScratchJr.layerTop
|
||||
});
|
||||
column.setAttribute('id', 'colnum');
|
||||
Grid.setScaleAndPosition(column, scaleMultiplier, 46 - 24, 74 + 1, 24, h + 24);
|
||||
var dy = 360 - offset;
|
||||
for (var j = 0; j < 360 / offset; j++) {
|
||||
var numj = newDiv(column, 0, dy, Grid.size, Grid.size, {
|
||||
|
||||
static setScaleAndPosition (grid, scale, x, y, w, h) {
|
||||
setProps(grid.style, {
|
||||
webkitTransform: 'translate(' + (-w / 2) + 'px, ' + (-h / 2) + 'px) ' +
|
||||
'scale(' + scale + ') ' +
|
||||
'translate(' + (w / 2 + x) + 'px, ' + (h / 2 + y) + 'px)'
|
||||
});
|
||||
}
|
||||
|
||||
static drawLines (grid, w, h) {
|
||||
var cnv = newCanvas(grid, 0, 0, w, h, {
|
||||
position: 'absolute'
|
||||
});
|
||||
cnv.style.opacity = 0.5;
|
||||
var ctx = cnv.getContext('2d');
|
||||
ctx.strokeStyle = '#B3B3B3';
|
||||
ctx.lineWidth = 1;
|
||||
var dx = size;
|
||||
// vertical
|
||||
for (var i = 0; i < 480 / size; i++) {
|
||||
ctx.moveTo(dx, 0);
|
||||
ctx.lineTo(dx, 360);
|
||||
ctx.stroke();
|
||||
dx += size;
|
||||
}
|
||||
var dy = size;
|
||||
// horizontal
|
||||
for (i = 0; i < 360 / size; i++) {
|
||||
ctx.moveTo(0, dy);
|
||||
ctx.lineTo(480, dy);
|
||||
ctx.stroke();
|
||||
dy += size;
|
||||
}
|
||||
if (isTablet) {
|
||||
cnv.ontouchstart = function (evt) {
|
||||
ScratchJr.stage.mouseDown(evt);
|
||||
};
|
||||
} else {
|
||||
cnv.onmousedown = function (evt) {
|
||||
ScratchJr.stage.mouseDown(evt);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
static createNumbering (w, h) {
|
||||
var row = newDiv(gn('stageframe'), 0, 0, w - 46 - 30, 24, {
|
||||
position: 'absolute',
|
||||
zIndex: 10
|
||||
zIndex: ScratchJr.layerTop
|
||||
});
|
||||
var py = newP(numj, Localization.localize('GRID_NUMBER', {
|
||||
N: j + 1
|
||||
}), {});
|
||||
py.setAttribute('class', 'stylelabel');
|
||||
dy -= offset;
|
||||
}
|
||||
};
|
||||
|
||||
Grid.createYcursor = function () {
|
||||
var num = newDiv(gn('colnum'), 0, 0, Grid.size, Grid.size, {
|
||||
position: 'absolute',
|
||||
zIndex: 20
|
||||
});
|
||||
num.setAttribute('class', 'circle');
|
||||
num.style.background = '#6a99c1';
|
||||
num.setAttribute('id', 'ycursor');
|
||||
var p = newP(num, 15, {});
|
||||
p.setAttribute('class', 'circlenum');
|
||||
};
|
||||
|
||||
Grid.createXcursor = function () {
|
||||
var num = newDiv(gn('rownum'), Grid.size, 0, Grid.size, Grid.size, {
|
||||
position: 'absolute',
|
||||
zIndex: 20
|
||||
});
|
||||
num.setAttribute('class', 'circle');
|
||||
num.style.background = '#6a99c1';
|
||||
num.setAttribute('id', 'xcursor');
|
||||
var p = newP(num, 1, {});
|
||||
p.setAttribute('class', 'circlenum');
|
||||
};
|
||||
|
||||
Grid.createCursor = function () {
|
||||
var gc = newDiv(gn('livegrid'), 0, 0, Grid.size + 2, Grid.size + 2, {
|
||||
position: 'absolute',
|
||||
zIndex: ScratchJr.layerAboveBottom
|
||||
});
|
||||
gc.setAttribute('id', 'circlenum');
|
||||
var cnv = newCanvas(gc, 0, 0, Grid.size + 2, Grid.size + 2, {
|
||||
position: 'absolute'
|
||||
});
|
||||
if (isTablet) {
|
||||
cnv.ontouchstart = function (evt) {
|
||||
Grid.mouseDownOnCursor(evt);
|
||||
};
|
||||
} else {
|
||||
cnv.onmousedown = function (evt) {
|
||||
Grid.mouseDownOnCursor(evt);
|
||||
};
|
||||
}
|
||||
var ctx = cnv.getContext('2d');
|
||||
ctx.globalAlpha = 0.5;
|
||||
ctx.fillStyle = '#28A5DA';
|
||||
ctx.strokeStyle = '#656e73';
|
||||
ctx.lineWidth = 3;
|
||||
ctx.strokeRect(3, 3, Grid.size - 6, Grid.size - 6);
|
||||
ctx.fillRect(3, 3, Grid.size - 6, Grid.size - 6);
|
||||
if (isTablet) {
|
||||
gc.ontouchstart = Grid.mouseDownOnCursor;
|
||||
} else {
|
||||
gc.onmousedown = Grid.mouseDownOnCursor;
|
||||
}
|
||||
};
|
||||
|
||||
Grid.mouseDownOnCursor = function (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
var pt = ScratchJr.stage.getStagePt(e);
|
||||
var spr = ScratchJr.getSprite();
|
||||
ScratchJr.stage.initialPoint = {
|
||||
x: pt.x,
|
||||
y: pt.y
|
||||
};
|
||||
Events.dragthumbnail = spr.div;
|
||||
Events.clearEvents();
|
||||
if (!ScratchJr.inFullscreen && spr) {
|
||||
Events.holdit(spr.div, ScratchJr.stage.startShaking);
|
||||
}
|
||||
ScratchJr.stage.setEvents();
|
||||
};
|
||||
|
||||
Grid.updateCursor = function () {
|
||||
if (Grid.hidden) {
|
||||
return;
|
||||
}
|
||||
if (ScratchJr.inFullscreen) {
|
||||
return;
|
||||
}
|
||||
if (!ScratchJr.stage.currentPage) {
|
||||
return;
|
||||
}
|
||||
if (!ScratchJr.getSprite()) {
|
||||
gn('circlenum').style.visibility = 'hidden';
|
||||
gn('xcursor').style.visibility = 'hidden';
|
||||
gn('ycursor').style.visibility = 'hidden';
|
||||
return;
|
||||
}
|
||||
var spr = gn(ScratchJr.stage.currentPage.currentSpriteName);
|
||||
if (!spr) {
|
||||
return;
|
||||
}
|
||||
var obj = spr.owner;
|
||||
var c = gn('circlenum');
|
||||
if (!c) {
|
||||
return;
|
||||
}
|
||||
var dx = obj.xcoor + Grid.size / 2;
|
||||
var dy = obj.ycoor - Grid.size / 2;
|
||||
gn('xcursor').style.visibility = 'visible';
|
||||
gn('ycursor').style.visibility = 'visible';
|
||||
gn('circlenum').style.visibility = 'visible';
|
||||
Grid.setCursorsValues(dx, dy);
|
||||
};
|
||||
|
||||
Grid.setCursorsValues = function (dx, dy) {
|
||||
var c = gn('circlenum');
|
||||
var numX = Math.round(dx / Grid.size);
|
||||
var numY = Math.round(dy / Grid.size);
|
||||
if (c.offsetLeft != (numX * 24)) {
|
||||
var xc = gn('xcursor');
|
||||
var xstate = ((numX < 1) || (numX > 20)) ? 'hidden' : 'visible';
|
||||
setProps(xc.style, {
|
||||
row.setAttribute('id', 'rownum');
|
||||
Grid.setScaleAndPosition(row, scaleMultiplier, 46 - 24, 75 + height, w - 46 - 30, 24);
|
||||
var offset = size;
|
||||
var dx = offset;
|
||||
for (var i = 0; i < 480 / offset; i++) {
|
||||
var num = newDiv(row, dx, 0, size, size, {
|
||||
position: 'absolute',
|
||||
zIndex: 10
|
||||
});
|
||||
var p = newP(num, Localization.localize('GRID_NUMBER', {
|
||||
N: (i + 1)
|
||||
}), {});
|
||||
p.setAttribute('class', 'stylelabel');
|
||||
dx += offset;
|
||||
}
|
||||
var column = newDiv(gn('stageframe'), 0, 0, 24, h + 24, {
|
||||
position: 'absolute',
|
||||
left: (numX * 24) + 'px',
|
||||
visibility: xstate
|
||||
});
|
||||
xc.childNodes[0].textContent = Localization.localize('GRID_NUMBER', {
|
||||
N: numX
|
||||
zIndex: ScratchJr.layerTop
|
||||
});
|
||||
column.setAttribute('id', 'colnum');
|
||||
Grid.setScaleAndPosition(column, scaleMultiplier, 46 - 24, 74 + 1, 24, h + 24);
|
||||
var dy = 360 - offset;
|
||||
for (var j = 0; j < 360 / offset; j++) {
|
||||
var numj = newDiv(column, 0, dy, size, size, {
|
||||
position: 'absolute',
|
||||
zIndex: 10
|
||||
});
|
||||
var py = newP(numj, Localization.localize('GRID_NUMBER', {
|
||||
N: j + 1
|
||||
}), {});
|
||||
py.setAttribute('class', 'stylelabel');
|
||||
dy -= offset;
|
||||
}
|
||||
}
|
||||
if (c.offsetTop != (numY * 24)) {
|
||||
var yc = gn('ycursor');
|
||||
var ystate = ((numY < 0) || (numY > 14)) ? 'hidden' : 'visible';
|
||||
setProps(yc.style, {
|
||||
|
||||
static createYcursor () {
|
||||
var num = newDiv(gn('colnum'), 0, 0, size, size, {
|
||||
position: 'absolute',
|
||||
zIndex: 20
|
||||
});
|
||||
num.setAttribute('class', 'circle');
|
||||
num.style.background = '#6a99c1';
|
||||
num.setAttribute('id', 'ycursor');
|
||||
var p = newP(num, 15, {});
|
||||
p.setAttribute('class', 'circlenum');
|
||||
}
|
||||
|
||||
static createXcursor () {
|
||||
var num = newDiv(gn('rownum'), size, 0, size, size, {
|
||||
position: 'absolute',
|
||||
zIndex: 20
|
||||
});
|
||||
num.setAttribute('class', 'circle');
|
||||
num.style.background = '#6a99c1';
|
||||
num.setAttribute('id', 'xcursor');
|
||||
var p = newP(num, 1, {});
|
||||
p.setAttribute('class', 'circlenum');
|
||||
}
|
||||
|
||||
static createCursor () {
|
||||
var gc = newDiv(gn('livegrid'), 0, 0, size + 2, size + 2, {
|
||||
position: 'absolute',
|
||||
zIndex: ScratchJr.layerAboveBottom
|
||||
});
|
||||
gc.setAttribute('id', 'circlenum');
|
||||
var cnv = newCanvas(gc, 0, 0, size + 2, size + 2, {
|
||||
position: 'absolute'
|
||||
});
|
||||
if (isTablet) {
|
||||
cnv.ontouchstart = function (evt) {
|
||||
Grid.mouseDownOnCursor(evt);
|
||||
};
|
||||
} else {
|
||||
cnv.onmousedown = function (evt) {
|
||||
Grid.mouseDownOnCursor(evt);
|
||||
};
|
||||
}
|
||||
var ctx = cnv.getContext('2d');
|
||||
ctx.globalAlpha = 0.5;
|
||||
ctx.fillStyle = '#28A5DA';
|
||||
ctx.strokeStyle = '#656e73';
|
||||
ctx.lineWidth = 3;
|
||||
ctx.strokeRect(3, 3, size - 6, size - 6);
|
||||
ctx.fillRect(3, 3, size - 6, size - 6);
|
||||
if (isTablet) {
|
||||
gc.ontouchstart = Grid.mouseDownOnCursor;
|
||||
} else {
|
||||
gc.onmousedown = Grid.mouseDownOnCursor;
|
||||
}
|
||||
}
|
||||
|
||||
static mouseDownOnCursor (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
var pt = ScratchJr.stage.getStagePt(e);
|
||||
var spr = ScratchJr.getSprite();
|
||||
ScratchJr.stage.initialPoint = {
|
||||
x: pt.x,
|
||||
y: pt.y
|
||||
};
|
||||
Events.dragthumbnail = spr.div;
|
||||
Events.clearEvents();
|
||||
if (!ScratchJr.inFullscreen && spr) {
|
||||
Events.holdit(spr.div, ScratchJr.stage.startShaking);
|
||||
}
|
||||
ScratchJr.stage.setEvents();
|
||||
}
|
||||
|
||||
static updateCursor () {
|
||||
if (hidden) {
|
||||
return;
|
||||
}
|
||||
if (ScratchJr.inFullscreen) {
|
||||
return;
|
||||
}
|
||||
if (!ScratchJr.stage.currentPage) {
|
||||
return;
|
||||
}
|
||||
if (!ScratchJr.getSprite()) {
|
||||
gn('circlenum').style.visibility = 'hidden';
|
||||
gn('xcursor').style.visibility = 'hidden';
|
||||
gn('ycursor').style.visibility = 'hidden';
|
||||
return;
|
||||
}
|
||||
var spr = gn(ScratchJr.stage.currentPage.currentSpriteName);
|
||||
if (!spr) {
|
||||
return;
|
||||
}
|
||||
var obj = spr.owner;
|
||||
var c = gn('circlenum');
|
||||
if (!c) {
|
||||
return;
|
||||
}
|
||||
var dx = obj.xcoor + size / 2;
|
||||
var dy = obj.ycoor - size / 2;
|
||||
gn('xcursor').style.visibility = 'visible';
|
||||
gn('ycursor').style.visibility = 'visible';
|
||||
gn('circlenum').style.visibility = 'visible';
|
||||
Grid.setCursorsValues(dx, dy);
|
||||
}
|
||||
|
||||
static setCursorsValues (dx, dy) {
|
||||
var c = gn('circlenum');
|
||||
var numX = Math.round(dx / size);
|
||||
var numY = Math.round(dy / size);
|
||||
if (c.offsetLeft != (numX * 24)) {
|
||||
var xc = gn('xcursor');
|
||||
var xstate = ((numX < 1) || (numX > 20)) ? 'hidden' : 'visible';
|
||||
setProps(xc.style, {
|
||||
position: 'absolute',
|
||||
left: (numX * 24) + 'px',
|
||||
visibility: xstate
|
||||
});
|
||||
xc.childNodes[0].textContent = Localization.localize('GRID_NUMBER', {
|
||||
N: numX
|
||||
});
|
||||
}
|
||||
if (c.offsetTop != (numY * 24)) {
|
||||
var yc = gn('ycursor');
|
||||
var ystate = ((numY < 0) || (numY > 14)) ? 'hidden' : 'visible';
|
||||
setProps(yc.style, {
|
||||
position: 'absolute',
|
||||
top: (numY * 24) + 'px',
|
||||
visibility: ystate
|
||||
});
|
||||
yc.childNodes[0].textContent = Localization.localize('GRID_NUMBER', {
|
||||
N: 15 - numY
|
||||
});
|
||||
}
|
||||
setProps(c.style, {
|
||||
position: 'absolute',
|
||||
top: (numY * 24) + 'px',
|
||||
visibility: ystate
|
||||
});
|
||||
yc.childNodes[0].textContent = Localization.localize('GRID_NUMBER', {
|
||||
N: 15 - numY
|
||||
left: ((numX - 1) * 24) + 'px'
|
||||
});
|
||||
}
|
||||
setProps(c.style, {
|
||||
position: 'absolute',
|
||||
top: (numY * 24) + 'px',
|
||||
left: ((numX - 1) * 24) + 'px'
|
||||
});
|
||||
};
|
||||
|
||||
Grid.hide = function (b) {
|
||||
Grid.hidden = b;
|
||||
var mystate = Grid.hidden ? 'hidden' : 'visible';
|
||||
gn('livegrid').style.visibility = mystate;
|
||||
gn('rownum').style.visibility = mystate;
|
||||
gn('colnum').style.visibility = mystate;
|
||||
if (ScratchJr.stage.currentPage) {
|
||||
mystate = !ScratchJr.getSprite() ? 'hidden' : mystate;
|
||||
static hide (b) {
|
||||
hidden = b;
|
||||
var mystate = hidden ? 'hidden' : 'visible';
|
||||
gn('livegrid').style.visibility = mystate;
|
||||
gn('rownum').style.visibility = mystate;
|
||||
gn('colnum').style.visibility = mystate;
|
||||
if (ScratchJr.stage.currentPage) {
|
||||
mystate = !ScratchJr.getSprite() ? 'hidden' : mystate;
|
||||
}
|
||||
gn('circlenum').style.visibility = mystate;
|
||||
gn('xcursor').style.visibility = mystate;
|
||||
gn('ycursor').style.visibility = mystate;
|
||||
}
|
||||
gn('circlenum').style.visibility = mystate;
|
||||
gn('xcursor').style.visibility = mystate;
|
||||
gn('ycursor').style.visibility = mystate;
|
||||
};
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,349 +1,367 @@
|
|||
var Record = function () {};
|
||||
import ScratchJr from '../ScratchJr';
|
||||
import Palette from './Palette';
|
||||
import Undo from './Undo';
|
||||
import iOS from '../../iPad/iOS';
|
||||
import ScratchAudio from '../../utils/ScratchAudio';
|
||||
import {frame, gn, newHTML, isTablet, isAndroid, setProps} from '../../utils/lib';
|
||||
|
||||
Record.isAndroid = isAndroid;
|
||||
Record.interval = null;
|
||||
Record.recordedSound = null;
|
||||
Record.isRecording = false;
|
||||
Record.isPlaying = false;
|
||||
Record.available = true;
|
||||
Record.error = false;
|
||||
Record.dialogOpen = false;
|
||||
Record.timeLimit = null;
|
||||
Record.playTimeLimit = null;
|
||||
let interval = null;
|
||||
let recordedSound = null;
|
||||
let isRecording = false;
|
||||
let isPlaying = false;
|
||||
let available = true;
|
||||
let error = false;
|
||||
let dialogOpen = false;
|
||||
let timeLimit = null;
|
||||
let playTimeLimit = null;
|
||||
|
||||
// Create the recording window, including buttons and volume indicators
|
||||
Record.init = function () {
|
||||
var modal = newHTML('div', 'record fade', frame);
|
||||
modal.setAttribute('id', 'recorddialog');
|
||||
var topbar = newHTML('div', 'toolbar', modal);
|
||||
var actions = newHTML('div', 'actions', topbar);
|
||||
newHTML('div', 'microphone', actions);
|
||||
var buttons = newHTML('div', 'recordbuttons', actions);
|
||||
var okbut = newHTML('div', 'recorddone', buttons);
|
||||
if (isTablet) {
|
||||
okbut.ontouchstart = Record.saveSoundAndClose;
|
||||
} else {
|
||||
okbut.onmousedown = Record.saveSoundAndClose;
|
||||
export default class Record {
|
||||
static get available () {
|
||||
return available;
|
||||
}
|
||||
var sc = newHTML('div', 'soundbox', modal);
|
||||
sc.setAttribute('id', 'soundbox');
|
||||
var sv = newHTML('div', 'soundvolume', sc);
|
||||
sv.setAttribute('id', 'soundvolume');
|
||||
for (var i = 0; i < 13; i++) {
|
||||
var si = newHTML('div', 'indicator', sv);
|
||||
newHTML('div', 'soundlevel', si);
|
||||
|
||||
static set available (newAvailable) {
|
||||
available = newAvailable;
|
||||
}
|
||||
var ctrol = newHTML('div', 'soundcontrols', sc);
|
||||
ctrol.setAttribute('id', 'soundcontrols');
|
||||
var lib = [['record', Record.record], ['stop', Record.stopSnd], ['play', Record.playSnd]];
|
||||
for (var j = 0; j < lib.length; j++) {
|
||||
Record.newToggleClicky(ctrol, 'id_', lib[j][0], lib[j][1]);
|
||||
|
||||
static get dialogOpen () {
|
||||
return dialogOpen;
|
||||
}
|
||||
};
|
||||
|
||||
// Dialog box hide/show
|
||||
Record.appear = function () {
|
||||
gn('backdrop').setAttribute('class', 'modal-backdrop fade in');
|
||||
setProps(gn('backdrop').style, {
|
||||
display: 'block'
|
||||
});
|
||||
gn('recorddialog').setAttribute('class', 'record fade in');
|
||||
ScratchJr.stopStrips();
|
||||
Record.dialogOpen = true;
|
||||
ScratchJr.onBackButtonCallback.push(Record.saveSoundandClose);
|
||||
};
|
||||
|
||||
Record.disappear = function () {
|
||||
setTimeout(function () {
|
||||
gn('backdrop').setAttribute('class', 'modal-backdrop fade');
|
||||
setProps(gn('backdrop').style, {
|
||||
display: 'none'
|
||||
});
|
||||
gn('recorddialog').setAttribute('class', 'record fade');
|
||||
}, 333);
|
||||
Record.dialogOpen = false;
|
||||
ScratchJr.onBackButtonCallback.pop();
|
||||
};
|
||||
|
||||
// Register toggle buttons and handlers
|
||||
Record.newToggleClicky = function (p, prefix, key, fcn) {
|
||||
var button = newHTML('div', 'controlwrap', p);
|
||||
newHTML('div', key + 'snd off', button);
|
||||
button.setAttribute('type', 'toggleclicky');
|
||||
button.setAttribute('id', prefix + key);
|
||||
if (fcn) {
|
||||
// Create the recording window, including buttons and volume indicators
|
||||
static init () {
|
||||
var modal = newHTML('div', 'record fade', frame);
|
||||
modal.setAttribute('id', 'recorddialog');
|
||||
var topbar = newHTML('div', 'toolbar', modal);
|
||||
var actions = newHTML('div', 'actions', topbar);
|
||||
newHTML('div', 'microphone', actions);
|
||||
var buttons = newHTML('div', 'recordbuttons', actions);
|
||||
var okbut = newHTML('div', 'recorddone', buttons);
|
||||
if (isTablet) {
|
||||
button.ontouchstart = function (evt) {
|
||||
fcn(evt);
|
||||
};
|
||||
okbut.ontouchstart = Record.saveSoundAndClose;
|
||||
} else {
|
||||
button.onmousedown = function (evt) {
|
||||
fcn(evt);
|
||||
};
|
||||
okbut.onmousedown = Record.saveSoundAndClose;
|
||||
}
|
||||
var sc = newHTML('div', 'soundbox', modal);
|
||||
sc.setAttribute('id', 'soundbox');
|
||||
var sv = newHTML('div', 'soundvolume', sc);
|
||||
sv.setAttribute('id', 'soundvolume');
|
||||
for (var i = 0; i < 13; i++) {
|
||||
var si = newHTML('div', 'indicator', sv);
|
||||
newHTML('div', 'soundlevel', si);
|
||||
}
|
||||
var ctrol = newHTML('div', 'soundcontrols', sc);
|
||||
ctrol.setAttribute('id', 'soundcontrols');
|
||||
var lib = [['record', Record.record], ['stop', Record.stopSnd], ['play', Record.playSnd]];
|
||||
for (var j = 0; j < lib.length; j++) {
|
||||
Record.newToggleClicky(ctrol, 'id_', lib[j][0], lib[j][1]);
|
||||
}
|
||||
}
|
||||
return button;
|
||||
};
|
||||
|
||||
// Toggle button appearance on/off
|
||||
Record.toggleButtonUI = function (button, newState) {
|
||||
var element = 'id_' + button;
|
||||
var newStateStr = (newState) ? 'on' : 'off';
|
||||
var attrclass = button + 'snd';
|
||||
gn(element).childNodes[0].setAttribute('class', attrclass + ' ' + newStateStr);
|
||||
};
|
||||
// Dialog box hide/show
|
||||
static appear () {
|
||||
gn('backdrop').setAttribute('class', 'modal-backdrop fade in');
|
||||
setProps(gn('backdrop').style, {
|
||||
display: 'block'
|
||||
});
|
||||
gn('recorddialog').setAttribute('class', 'record fade in');
|
||||
ScratchJr.stopStrips();
|
||||
dialogOpen = true;
|
||||
ScratchJr.onBackButtonCallback.push(Record.saveSoundandClose);
|
||||
}
|
||||
|
||||
// Volume UI updater
|
||||
Record.updateVolume = function (f) {
|
||||
var num = Math.round(f * 13);
|
||||
var div = gn('soundvolume');
|
||||
if (!Record.isRecording) {
|
||||
num = 0;
|
||||
}
|
||||
for (var i = 0; i < 13; i++) {
|
||||
div.childNodes[i].childNodes[0].setAttribute('class', ((i > num) ? 'soundlevel off' : 'soundlevel on'));
|
||||
}
|
||||
};
|
||||
|
||||
// Stop recording UI and turn off volume levels
|
||||
Record.recordUIoff = function () {
|
||||
Record.toggleButtonUI('record', false);
|
||||
var div = gn('soundvolume');
|
||||
for (var i = 0; i < gn('soundvolume').childElementCount; i++) {
|
||||
div.childNodes[i].childNodes[0].setAttribute('class', 'soundlevel off');
|
||||
}
|
||||
};
|
||||
|
||||
// On press record button
|
||||
Record.record = function (e) {
|
||||
if (Record.error) {
|
||||
Record.killRecorder(e);
|
||||
return;
|
||||
}
|
||||
if (Record.isPlaying) {
|
||||
Record.stopPlayingSound(doRecord);
|
||||
} else {
|
||||
doRecord();
|
||||
}
|
||||
function doRecord () {
|
||||
if (Record.isRecording) {
|
||||
Record.stopRecording(); // Stop if we're already recording
|
||||
} else {
|
||||
iOS.sndrecord(Record.startRecording); // Start a recording
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Record.startRecording = function (filename) {
|
||||
if (parseInt(filename) < 0) {
|
||||
// Error in getting record filename - go back to editor
|
||||
Record.recordedSound = undefined;
|
||||
Record.isRecording = false;
|
||||
Record.killRecorder();
|
||||
Palette.selectCategory(3);
|
||||
} else {
|
||||
// Save recording's filename for later
|
||||
Record.recordedSound = filename;
|
||||
Record.isRecording = true;
|
||||
Record.error = false;
|
||||
Record.soundname = filename;
|
||||
Record.toggleButtonUI('record', true);
|
||||
var poll = function () {
|
||||
iOS.volume(Record.updateVolume, Record.recordError);
|
||||
};
|
||||
Record.interval = setInterval(poll, 33);
|
||||
Record.timeLimit = setTimeout(function () {
|
||||
if (Record.isRecording) {
|
||||
Record.stopRecording();
|
||||
}
|
||||
}, 60000);
|
||||
}
|
||||
};
|
||||
|
||||
// Press the play button
|
||||
Record.playSnd = function (e) {
|
||||
if (Record.error) {
|
||||
Record.killRecorder(e);
|
||||
return;
|
||||
}
|
||||
if (!Record.recordedSound) {
|
||||
return;
|
||||
}
|
||||
if (Record.isPlaying) {
|
||||
Record.stopPlayingSound();
|
||||
} else {
|
||||
if (Record.isRecording) {
|
||||
Record.stopRecording(Record.startPlaying);
|
||||
} else {
|
||||
Record.startPlaying();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Start playing the sound and switch UI appropriately
|
||||
Record.startPlaying = function () {
|
||||
iOS.startplay(Record.timeOutPlay);
|
||||
Record.toggleButtonUI('play', true);
|
||||
Record.isPlaying = true;
|
||||
};
|
||||
|
||||
// Gets the sound duration from iOS and changes play UI state after time
|
||||
Record.timeOutPlay = function (timeout) {
|
||||
if (parseInt(timeout) < 0) {
|
||||
timeout = 0.1; // Error - stop playing immediately
|
||||
}
|
||||
Record.playTimeLimit = setTimeout(function () {
|
||||
Record.toggleButtonUI('play', false);
|
||||
Record.isPlaying = false;
|
||||
}, timeout * 1000);
|
||||
};
|
||||
|
||||
// Press on stop
|
||||
Record.stopSnd = function (e) {
|
||||
if (Record.error) {
|
||||
Record.killRecorder(e);
|
||||
return;
|
||||
}
|
||||
if (!Record.recordedSound) {
|
||||
return;
|
||||
}
|
||||
Record.flashStopButton();
|
||||
if (Record.isRecording) {
|
||||
Record.stopRecording();
|
||||
} else if (Record.isPlaying) {
|
||||
Record.stopPlayingSound();
|
||||
}
|
||||
};
|
||||
|
||||
Record.flashStopButton = function () {
|
||||
Record.toggleButtonUI('stop', true);
|
||||
setTimeout(function () {
|
||||
Record.toggleButtonUI('stop', false);
|
||||
}, 200);
|
||||
};
|
||||
|
||||
// Stop playing the sound and switch UI appropriately
|
||||
Record.stopPlayingSound = function (fcn) {
|
||||
iOS.stopplay(fcn);
|
||||
Record.toggleButtonUI('play', false);
|
||||
Record.isPlaying = false;
|
||||
window.clearTimeout(Record.playTimeLimit);
|
||||
Record.playTimeLimit = null;
|
||||
};
|
||||
|
||||
// Stop the volume monitor and recording
|
||||
Record.stopRecording = function (fcn) {
|
||||
if (Record.timeLimit != null) {
|
||||
clearTimeout(Record.timeLimit);
|
||||
Record.timeLimit = null;
|
||||
}
|
||||
if (Record.interval != null) {
|
||||
window.clearInterval(Record.interval);
|
||||
Record.interval = null;
|
||||
static disappear () {
|
||||
setTimeout(function () {
|
||||
Record.volumeCheckStopped(fcn);
|
||||
}, 33);
|
||||
} else {
|
||||
Record.volumeCheckStopped(fcn);
|
||||
gn('backdrop').setAttribute('class', 'modal-backdrop fade');
|
||||
setProps(gn('backdrop').style, {
|
||||
display: 'none'
|
||||
});
|
||||
gn('recorddialog').setAttribute('class', 'record fade');
|
||||
}, 333);
|
||||
dialogOpen = false;
|
||||
ScratchJr.onBackButtonCallback.pop();
|
||||
}
|
||||
};
|
||||
|
||||
Record.volumeCheckStopped = function (fcn) {
|
||||
Record.isRecording = false;
|
||||
Record.recordUIoff();
|
||||
iOS.recordstop(fcn);
|
||||
};
|
||||
|
||||
// Press OK (check)
|
||||
Record.saveSoundAndClose = function () {
|
||||
if (Record.error || !Record.recordedSound) {
|
||||
Record.killRecorder();
|
||||
} else {
|
||||
if (Record.isPlaying) {
|
||||
Record.stopPlayingSound(Record.closeContinueSave);
|
||||
} else {
|
||||
if (Record.isRecording) {
|
||||
Record.stopRecording(Record.closeContinueSave);
|
||||
// Register toggle buttons and handlers
|
||||
static newToggleClicky (p, prefix, key, fcn) {
|
||||
var button = newHTML('div', 'controlwrap', p);
|
||||
newHTML('div', key + 'snd off', button);
|
||||
button.setAttribute('type', 'toggleclicky');
|
||||
button.setAttribute('id', prefix + key);
|
||||
if (fcn) {
|
||||
if (isTablet) {
|
||||
button.ontouchstart = function (evt) {
|
||||
fcn(evt);
|
||||
};
|
||||
} else {
|
||||
Record.closeContinueSave();
|
||||
button.onmousedown = function (evt) {
|
||||
fcn(evt);
|
||||
};
|
||||
}
|
||||
}
|
||||
return button;
|
||||
}
|
||||
|
||||
// Toggle button appearance on/off
|
||||
static toggleButtonUI (button, newState) {
|
||||
var element = 'id_' + button;
|
||||
var newStateStr = (newState) ? 'on' : 'off';
|
||||
var attrclass = button + 'snd';
|
||||
gn(element).childNodes[0].setAttribute('class', attrclass + ' ' + newStateStr);
|
||||
}
|
||||
|
||||
// Volume UI updater
|
||||
static updateVolume (f) {
|
||||
var num = Math.round(f * 13);
|
||||
var div = gn('soundvolume');
|
||||
if (!isRecording) {
|
||||
num = 0;
|
||||
}
|
||||
for (var i = 0; i < 13; i++) {
|
||||
div.childNodes[i].childNodes[0].setAttribute('class', ((i > num) ? 'soundlevel off' : 'soundlevel on'));
|
||||
}
|
||||
}
|
||||
|
||||
// Stop recording UI and turn off volume levels
|
||||
static recordUIoff () {
|
||||
Record.toggleButtonUI('record', false);
|
||||
var div = gn('soundvolume');
|
||||
for (var i = 0; i < gn('soundvolume').childElementCount; i++) {
|
||||
div.childNodes[i].childNodes[0].setAttribute('class', 'soundlevel off');
|
||||
}
|
||||
}
|
||||
|
||||
// On press record button
|
||||
static record (e) {
|
||||
if (error) {
|
||||
Record.killRecorder(e);
|
||||
return;
|
||||
}
|
||||
if (isPlaying) {
|
||||
Record.stopPlayingSound(doRecord);
|
||||
} else {
|
||||
doRecord();
|
||||
}
|
||||
function doRecord () {
|
||||
if (isRecording) {
|
||||
Record.stopRecording(); // Stop if we're already recording
|
||||
} else {
|
||||
iOS.sndrecord(Record.startRecording); // Start a recording
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Record.closeContinueSave = function () {
|
||||
iOS.recorddisappear('YES', Record.getUserSound);
|
||||
};
|
||||
|
||||
Record.closeContinueRemove = function () {
|
||||
// don't get the sound - proceed right to tearDown
|
||||
iOS.recorddisappear('NO', Record.tearDownRecorder);
|
||||
};
|
||||
|
||||
Record.getUserSound = function () {
|
||||
Record.isRecording = false;
|
||||
if (!Record.isAndroid) {
|
||||
iOS.getmedia(Record.recordedSound, Record.registerProjectSound);
|
||||
} else {
|
||||
// On Android, just pass URL
|
||||
Record.registerProjectSound(null);
|
||||
}
|
||||
};
|
||||
|
||||
Record.registerProjectSound = function (data) {
|
||||
function loadingDone (snd) {
|
||||
if (snd != 'error') {
|
||||
var spr = ScratchJr.getSprite();
|
||||
var page = spr.div.parentNode.owner;
|
||||
spr.sounds.push(Record.recordedSound);
|
||||
Undo.record({
|
||||
action: 'recordsound',
|
||||
who: spr.id,
|
||||
where: page.id,
|
||||
sound: Record.recordedSound
|
||||
});
|
||||
ScratchJr.storyStart('Record.registerProjectSound');
|
||||
}
|
||||
Record.tearDownRecorder();
|
||||
Palette.selectCategory(3);
|
||||
}
|
||||
if (!Record.isAndroid) {
|
||||
ScratchAudio.loadFromData(Record.recordedSound, data, loadingDone);
|
||||
} else {
|
||||
// On Android, just pass URL
|
||||
ScratchAudio.loadFromLocal(Record.recordedSound, loadingDone);
|
||||
}
|
||||
};
|
||||
|
||||
// Called on error - remove everything and hide the recorder
|
||||
Record.killRecorder = function () {
|
||||
// Inform iOS and then tear-down
|
||||
if (Record.isPlaying) {
|
||||
Record.stopPlayingSound(Record.closeContinueRemove); // stop playing and tear-down
|
||||
} else {
|
||||
if (Record.isRecording) {
|
||||
Record.stopRecording(Record.closeContinueRemove); // stop recording and tear-down
|
||||
static startRecording (filename) {
|
||||
if (parseInt(filename) < 0) {
|
||||
// Error in getting record filename - go back to editor
|
||||
recordedSound = undefined;
|
||||
isRecording = false;
|
||||
Record.killRecorder();
|
||||
Palette.selectCategory(3);
|
||||
} else {
|
||||
Record.closeContinueRemove();
|
||||
// Save recording's filename for later
|
||||
recordedSound = filename;
|
||||
isRecording = true;
|
||||
error = false;
|
||||
Record.soundname = filename;
|
||||
Record.toggleButtonUI('record', true);
|
||||
var poll = function () {
|
||||
iOS.volume(Record.updateVolume, Record.recordError);
|
||||
};
|
||||
interval = setInterval(poll, 33);
|
||||
timeLimit = setTimeout(function () {
|
||||
if (isRecording) {
|
||||
Record.stopRecording();
|
||||
}
|
||||
}, 60000);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Record.tearDownRecorder = function () {
|
||||
// Clear errors
|
||||
if (Record.error) {
|
||||
Record.error = false;
|
||||
// Press the play button
|
||||
static playSnd (e) {
|
||||
if (error) {
|
||||
Record.killRecorder(e);
|
||||
return;
|
||||
}
|
||||
if (!recordedSound) {
|
||||
return;
|
||||
}
|
||||
if (isPlaying) {
|
||||
Record.stopPlayingSound();
|
||||
} else {
|
||||
if (isRecording) {
|
||||
Record.stopRecording(Record.startPlaying);
|
||||
} else {
|
||||
Record.startPlaying();
|
||||
}
|
||||
}
|
||||
}
|
||||
// Refresh audio context
|
||||
ScratchAudio.firstTime = true;
|
||||
Record.isRecording = false;
|
||||
Record.recordedSound = null;
|
||||
// Hide the dialog
|
||||
Record.disappear();
|
||||
};
|
||||
|
||||
// Called when the app is put into the background
|
||||
Record.recordError = function () {
|
||||
Record.error = true;
|
||||
Record.killRecorder();
|
||||
};
|
||||
// Start playing the sound and switch UI appropriately
|
||||
static startPlaying () {
|
||||
iOS.startplay(Record.timeOutPlay);
|
||||
Record.toggleButtonUI('play', true);
|
||||
isPlaying = true;
|
||||
}
|
||||
|
||||
// Gets the sound duration from iOS and changes play UI state after time
|
||||
static timeOutPlay (timeout) {
|
||||
if (parseInt(timeout) < 0) {
|
||||
timeout = 0.1; // Error - stop playing immediately
|
||||
}
|
||||
playTimeLimit = setTimeout(function () {
|
||||
Record.toggleButtonUI('play', false);
|
||||
isPlaying = false;
|
||||
}, timeout * 1000);
|
||||
}
|
||||
|
||||
// Press on stop
|
||||
static stopSnd (e) {
|
||||
if (error) {
|
||||
Record.killRecorder(e);
|
||||
return;
|
||||
}
|
||||
if (!recordedSound) {
|
||||
return;
|
||||
}
|
||||
Record.flashStopButton();
|
||||
if (isRecording) {
|
||||
Record.stopRecording();
|
||||
} else if (isPlaying) {
|
||||
Record.stopPlayingSound();
|
||||
}
|
||||
}
|
||||
|
||||
static flashStopButton () {
|
||||
Record.toggleButtonUI('stop', true);
|
||||
setTimeout(function () {
|
||||
Record.toggleButtonUI('stop', false);
|
||||
}, 200);
|
||||
}
|
||||
|
||||
// Stop playing the sound and switch UI appropriately
|
||||
static stopPlayingSound (fcn) {
|
||||
iOS.stopplay(fcn);
|
||||
Record.toggleButtonUI('play', false);
|
||||
isPlaying = false;
|
||||
window.clearTimeout(playTimeLimit);
|
||||
playTimeLimit = null;
|
||||
}
|
||||
|
||||
// Stop the volume monitor and recording
|
||||
static stopRecording (fcn) {
|
||||
if (timeLimit != null) {
|
||||
clearTimeout(timeLimit);
|
||||
timeLimit = null;
|
||||
}
|
||||
if (interval != null) {
|
||||
window.clearInterval(interval);
|
||||
interval = null;
|
||||
setTimeout(function () {
|
||||
Record.volumeCheckStopped(fcn);
|
||||
}, 33);
|
||||
} else {
|
||||
Record.volumeCheckStopped(fcn);
|
||||
}
|
||||
}
|
||||
|
||||
static volumeCheckStopped (fcn) {
|
||||
isRecording = false;
|
||||
Record.recordUIoff();
|
||||
iOS.recordstop(fcn);
|
||||
}
|
||||
|
||||
// Press OK (check)
|
||||
static saveSoundAndClose () {
|
||||
if (error || !recordedSound) {
|
||||
Record.killRecorder();
|
||||
} else {
|
||||
if (isPlaying) {
|
||||
Record.stopPlayingSound(Record.closeContinueSave);
|
||||
} else {
|
||||
if (isRecording) {
|
||||
Record.stopRecording(Record.closeContinueSave);
|
||||
} else {
|
||||
Record.closeContinueSave();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static closeContinueSave () {
|
||||
iOS.recorddisappear('YES', Record.getUserSound);
|
||||
}
|
||||
|
||||
static closeContinueRemove () {
|
||||
// don't get the sound - proceed right to tearDown
|
||||
iOS.recorddisappear('NO', Record.tearDownRecorder);
|
||||
}
|
||||
|
||||
static getUserSound () {
|
||||
isRecording = false;
|
||||
if (!isAndroid) {
|
||||
iOS.getmedia(recordedSound, Record.registerProjectSound);
|
||||
} else {
|
||||
// On Android, just pass URL
|
||||
Record.registerProjectSound(null);
|
||||
}
|
||||
}
|
||||
|
||||
static registerProjectSound (data) {
|
||||
function loadingDone (snd) {
|
||||
if (snd != 'error') {
|
||||
var spr = ScratchJr.getSprite();
|
||||
var page = spr.div.parentNode.owner;
|
||||
spr.sounds.push(recordedSound);
|
||||
Undo.record({
|
||||
action: 'recordsound',
|
||||
who: spr.id,
|
||||
where: page.id,
|
||||
sound: recordedSound
|
||||
});
|
||||
ScratchJr.storyStart('Record.registerProjectSound');
|
||||
}
|
||||
Record.tearDownRecorder();
|
||||
Palette.selectCategory(3);
|
||||
}
|
||||
if (!isAndroid) {
|
||||
ScratchAudio.loadFromData(recordedSound, data, loadingDone);
|
||||
} else {
|
||||
// On Android, just pass URL
|
||||
ScratchAudio.loadFromLocal(recordedSound, loadingDone);
|
||||
}
|
||||
}
|
||||
|
||||
// Called on error - remove everything and hide the recorder
|
||||
static killRecorder () {
|
||||
// Inform iOS and then tear-down
|
||||
if (isPlaying) {
|
||||
Record.stopPlayingSound(Record.closeContinueRemove); // stop playing and tear-down
|
||||
} else {
|
||||
if (isRecording) {
|
||||
Record.stopRecording(Record.closeContinueRemove); // stop recording and tear-down
|
||||
} else {
|
||||
Record.closeContinueRemove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static tearDownRecorder () {
|
||||
// Clear errors
|
||||
if (error) {
|
||||
error = false;
|
||||
}
|
||||
// Refresh audio context
|
||||
ScratchAudio.firstTime = true;
|
||||
isRecording = false;
|
||||
recordedSound = null;
|
||||
// Hide the dialog
|
||||
Record.disappear();
|
||||
}
|
||||
|
||||
// Called when the app is put into the background
|
||||
static recordError () {
|
||||
error = true;
|
||||
Record.killRecorder();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,308 +1,328 @@
|
|||
var ScriptsPane = function () {};
|
||||
|
||||
ScriptsPane.scroll = undefined;
|
||||
import ScratchJr from '../ScratchJr';
|
||||
import Project from './Project';
|
||||
import Thumbs from './Thumbs';
|
||||
import Palette from './Palette';
|
||||
import Undo from './Undo';
|
||||
import Events from '../../utils/Events';
|
||||
import Scroll from './Scroll';
|
||||
import Menu from './Menu';
|
||||
import ScratchAudio from '../../utils/ScratchAudio';
|
||||
import {frame, gn, localx, localy, newHTML, isTablet,
|
||||
globalx, globaly, setCanvasSize, getDocumentHeight, frame} from '../../utils/lib';
|
||||
|
||||
ScriptsPane.watermark;
|
||||
let scroll = undefined;
|
||||
let watermark;
|
||||
|
||||
ScriptsPane.createScripts = function (parent) {
|
||||
var div = newHTML('div', 'scripts', parent);
|
||||
div.setAttribute('id', 'scripts');
|
||||
ScriptsPane.watermark = newHTML('div', 'watermark', div);
|
||||
var h = Math.max(getDocumentHeight(), frame.offsetHeight);
|
||||
setCanvasSize(div, div.offsetWidth, h - div.offsetTop);
|
||||
ScriptsPane.scroll = new Scroll(div, 'scriptscontainer', div.offsetWidth,
|
||||
h - div.offsetTop, ScratchJr.getActiveScript, ScratchJr.getBlocks);
|
||||
};
|
||||
|
||||
ScriptsPane.setActiveScript = function (sprname) {
|
||||
var currentsc = gn(sprname + '_scripts');
|
||||
if (!currentsc) {
|
||||
// Sprite not found
|
||||
return;
|
||||
export default class ScriptsPane {
|
||||
static get scroll () {
|
||||
return scroll;
|
||||
}
|
||||
ScratchJr.stage.currentPage.setCurrentSprite(gn(sprname).owner);
|
||||
currentsc.owner.activate();
|
||||
currentsc.parentNode.ontouchstart = function (evt) {
|
||||
currentsc.owner.scriptsMouseDown(evt);
|
||||
};
|
||||
ScriptsPane.scroll.update();
|
||||
};
|
||||
|
||||
ScriptsPane.runBlock = function (e, div) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
var b = div.owner.findFirst();
|
||||
// if (b.aStart) b = b.next;
|
||||
if (!b) {
|
||||
return;
|
||||
static get watermark () {
|
||||
return watermark;
|
||||
}
|
||||
ScratchJr.runtime.addRunScript(ScratchJr.getSprite(), b);
|
||||
ScratchJr.startCurrentPageStrips(['ontouch']);
|
||||
ScratchJr.userStart = true;
|
||||
};
|
||||
|
||||
ScriptsPane.prepareToDrag = function (e) {
|
||||
e.preventDefault();
|
||||
var pt = Events.getTargetPoint(e);
|
||||
ScriptsPane.pickBlock(pt.x, pt.y, e);
|
||||
};
|
||||
static createScripts (parent) {
|
||||
var div = newHTML('div', 'scripts', parent);
|
||||
div.setAttribute('id', 'scripts');
|
||||
watermark = newHTML('div', 'watermark', div);
|
||||
var h = Math.max(getDocumentHeight(), frame.offsetHeight);
|
||||
setCanvasSize(div, div.offsetWidth, h - div.offsetTop);
|
||||
scroll = new Scroll(div, 'scriptscontainer', div.offsetWidth,
|
||||
h - div.offsetTop, ScratchJr.getActiveScript, ScratchJr.getBlocks);
|
||||
}
|
||||
|
||||
ScriptsPane.pickBlock = function (x, y, e) {
|
||||
if (!ScratchJr.runtime.inactive()) {
|
||||
ScratchJr.stopStrips();
|
||||
}
|
||||
ScriptsPane.cleanCarets();
|
||||
ScratchJr.unfocus(e);
|
||||
var sc = ScratchJr.getActiveScript().owner;
|
||||
sc.dragList = sc.findGroup(Events.dragthumbnail.owner);
|
||||
sc.flowCaret = null;
|
||||
var sy = Events.dragthumbnail.parentNode.scrollTop;
|
||||
var sx = Events.dragthumbnail.parentNode.scrollLeft;
|
||||
Events.dragmousex = x;
|
||||
Events.dragmousey = y;
|
||||
var lpt = {
|
||||
x: localx(Events.dragthumbnail.parentNode, x),
|
||||
y: localy(Events.dragthumbnail.parentNode, y)
|
||||
};
|
||||
var mx = Events.dragmousex - globalx(Events.dragDiv) - lpt.x + Events.dragthumbnail.left;
|
||||
var my = Events.dragmousey - globaly(Events.dragDiv) - lpt.y + Events.dragthumbnail.top;
|
||||
var mtx = new WebKitCSSMatrix(window.getComputedStyle(Events.dragthumbnail).webkitTransform);
|
||||
my -= sy;
|
||||
mx -= sx;
|
||||
Events.dragcanvas = Events.dragthumbnail;
|
||||
Events.dragcanvas.origin = 'scripts';
|
||||
Events.dragcanvas.startx = mtx.m41;
|
||||
Events.dragcanvas.starty = mtx.m42;
|
||||
if (!Events.dragcanvas.isReporter && Events.dragcanvas.parentNode) {
|
||||
Events.dragcanvas.parentNode.removeChild(Events.dragcanvas);
|
||||
}
|
||||
Events.move3D(Events.dragcanvas, mx, my);
|
||||
Events.dragcanvas.style.zIndex = ScratchJr.dragginLayer;
|
||||
Events.dragDiv.appendChild(Events.dragcanvas);
|
||||
var b = Events.dragcanvas.owner;
|
||||
b.detachBlock();
|
||||
// b.lift();
|
||||
if (Events.dragcanvas.isReporter) {
|
||||
return;
|
||||
}
|
||||
ScratchJr.getActiveScript().owner.prepareCaret(b);
|
||||
for (var i = 1; i < sc.dragList.length; i++) {
|
||||
b = sc.dragList[i];
|
||||
var pos = new WebKitCSSMatrix(window.getComputedStyle(b.div).webkitTransform);
|
||||
var dx = pos.m41 - mtx.m41;
|
||||
var dy = pos.m42 - mtx.m42;
|
||||
b.moveBlock(dx, dy);
|
||||
// b.lift();
|
||||
Events.dragcanvas.appendChild(b.div);
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////
|
||||
// Events MouseMove
|
||||
////////////////////////////////////////////////
|
||||
|
||||
ScriptsPane.draggingBlock = function (e) {
|
||||
e.preventDefault();
|
||||
var pt = Events.getTargetPoint(e);
|
||||
var dx = pt.x - Events.dragmousex;
|
||||
var dy = pt.y - Events.dragmousey;
|
||||
Events.move3D(Events.dragcanvas, dx, dy);
|
||||
ScriptsPane.blockFeedback(Events.dragcanvas.left, Events.dragcanvas.top, e);
|
||||
};
|
||||
|
||||
ScriptsPane.blockFeedback = function (dx, dy, e) {
|
||||
var script = ScratchJr.getActiveScript().owner;
|
||||
var limit = gn('palette').parentNode.offsetTop + gn('palette').parentNode.offsetHeight;
|
||||
var ycor = dy + Events.dragcanvas.offsetHeight;
|
||||
if (ycor < limit) {
|
||||
script.removeCaret();
|
||||
} else {
|
||||
script.removeCaret();
|
||||
script.insertCaret(dx, dy);
|
||||
}
|
||||
var thumb;
|
||||
switch (Palette.getLandingPlace(script.dragList[0].div, e)) {
|
||||
case 'library':
|
||||
thumb = Palette.getHittedThumb(script.dragList[0].div, gn('spritecc'));
|
||||
if (thumb && (gn(thumb.owner).owner.type == ScratchJr.getSprite().type)) {
|
||||
Thumbs.quickHighlight(thumb);
|
||||
} else {
|
||||
thumb = undefined;
|
||||
static setActiveScript (sprname) {
|
||||
var currentsc = gn(sprname + '_scripts');
|
||||
if (!currentsc) {
|
||||
// Sprite not found
|
||||
return;
|
||||
}
|
||||
ScratchJr.stage.currentPage.setCurrentSprite(gn(sprname).owner);
|
||||
currentsc.owner.activate();
|
||||
currentsc.parentNode.ontouchstart = function (evt) {
|
||||
currentsc.owner.scriptsMouseDown(evt);
|
||||
};
|
||||
scroll.update();
|
||||
}
|
||||
|
||||
static runBlock (e, div) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
var b = div.owner.findFirst();
|
||||
// if (b.aStart) b = b.next;
|
||||
if (!b) {
|
||||
return;
|
||||
}
|
||||
ScratchJr.runtime.addRunScript(ScratchJr.getSprite(), b);
|
||||
ScratchJr.startCurrentPageStrips(['ontouch']);
|
||||
ScratchJr.userStart = true;
|
||||
}
|
||||
|
||||
static prepareToDrag (e) {
|
||||
e.preventDefault();
|
||||
var pt = Events.getTargetPoint(e);
|
||||
ScriptsPane.pickBlock(pt.x, pt.y, e);
|
||||
}
|
||||
|
||||
static pickBlock (x, y, e) {
|
||||
if (!ScratchJr.runtime.inactive()) {
|
||||
ScratchJr.stopStrips();
|
||||
}
|
||||
ScriptsPane.cleanCarets();
|
||||
ScratchJr.unfocus(e);
|
||||
var sc = ScratchJr.getActiveScript().owner;
|
||||
sc.dragList = sc.findGroup(Events.dragthumbnail.owner);
|
||||
sc.flowCaret = null;
|
||||
var sy = Events.dragthumbnail.parentNode.scrollTop;
|
||||
var sx = Events.dragthumbnail.parentNode.scrollLeft;
|
||||
Events.dragmousex = x;
|
||||
Events.dragmousey = y;
|
||||
var lpt = {
|
||||
x: localx(Events.dragthumbnail.parentNode, x),
|
||||
y: localy(Events.dragthumbnail.parentNode, y)
|
||||
};
|
||||
var mx = Events.dragmousex - globalx(Events.dragDiv) - lpt.x + Events.dragthumbnail.left;
|
||||
var my = Events.dragmousey - globaly(Events.dragDiv) - lpt.y + Events.dragthumbnail.top;
|
||||
var mtx = new WebKitCSSMatrix(window.getComputedStyle(Events.dragthumbnail).webkitTransform);
|
||||
my -= sy;
|
||||
mx -= sx;
|
||||
Events.dragcanvas = Events.dragthumbnail;
|
||||
Events.dragcanvas.origin = 'scripts';
|
||||
Events.dragcanvas.startx = mtx.m41;
|
||||
Events.dragcanvas.starty = mtx.m42;
|
||||
if (!Events.dragcanvas.isReporter && Events.dragcanvas.parentNode) {
|
||||
Events.dragcanvas.parentNode.removeChild(Events.dragcanvas);
|
||||
}
|
||||
Events.move3D(Events.dragcanvas, mx, my);
|
||||
Events.dragcanvas.style.zIndex = ScratchJr.dragginLayer;
|
||||
Events.dragDiv.appendChild(Events.dragcanvas);
|
||||
var b = Events.dragcanvas.owner;
|
||||
b.detachBlock();
|
||||
// b.lift();
|
||||
if (Events.dragcanvas.isReporter) {
|
||||
return;
|
||||
}
|
||||
ScratchJr.getActiveScript().owner.prepareCaret(b);
|
||||
for (var i = 1; i < sc.dragList.length; i++) {
|
||||
b = sc.dragList[i];
|
||||
var pos = new WebKitCSSMatrix(window.getComputedStyle(b.div).webkitTransform);
|
||||
var dx = pos.m41 - mtx.m41;
|
||||
var dy = pos.m42 - mtx.m42;
|
||||
b.moveBlock(dx, dy);
|
||||
// b.lift();
|
||||
Events.dragcanvas.appendChild(b.div);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////
|
||||
// Events MouseMove
|
||||
////////////////////////////////////////////////
|
||||
|
||||
static draggingBlock (e) {
|
||||
e.preventDefault();
|
||||
var pt = Events.getTargetPoint(e);
|
||||
var dx = pt.x - Events.dragmousex;
|
||||
var dy = pt.y - Events.dragmousey;
|
||||
Events.move3D(Events.dragcanvas, dx, dy);
|
||||
ScriptsPane.blockFeedback(Events.dragcanvas.left, Events.dragcanvas.top, e);
|
||||
}
|
||||
|
||||
static blockFeedback (dx, dy, e) {
|
||||
var script = ScratchJr.getActiveScript().owner;
|
||||
var limit = gn('palette').parentNode.offsetTop + gn('palette').parentNode.offsetHeight;
|
||||
var ycor = dy + Events.dragcanvas.offsetHeight;
|
||||
if (ycor < limit) {
|
||||
script.removeCaret();
|
||||
} else {
|
||||
script.removeCaret();
|
||||
script.insertCaret(dx, dy);
|
||||
}
|
||||
var thumb;
|
||||
switch (Palette.getLandingPlace(script.dragList[0].div, e)) {
|
||||
case 'library':
|
||||
thumb = Palette.getHittedThumb(script.dragList[0].div, gn('spritecc'));
|
||||
if (thumb && (gn(thumb.owner).owner.type == ScratchJr.getSprite().type)) {
|
||||
Thumbs.quickHighlight(thumb);
|
||||
} else {
|
||||
thumb = undefined;
|
||||
}
|
||||
for (var i = 0; i < gn('spritecc').childElementCount; i++) {
|
||||
var spr = gn('spritecc').childNodes[i];
|
||||
if (spr.nodeName == 'FORM') {
|
||||
continue;
|
||||
}
|
||||
if (thumb && (thumb.id != spr.id)) {
|
||||
Thumbs.quickRestore(spr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ScriptsPane.removeLibCaret();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////
|
||||
// Events MouseUP
|
||||
////////////////////////////////////////////////
|
||||
|
||||
static dropBlock (e, el) {
|
||||
e.preventDefault();
|
||||
var sc = ScratchJr.getActiveScript();
|
||||
var spr = sc.owner.spr.id;
|
||||
var page = ScratchJr.stage.currentPage;
|
||||
switch (Palette.getLandingPlace(el, e)) {
|
||||
case 'scripts':
|
||||
var dx = localx(sc, el.left);
|
||||
var dy = localy(sc, el.top);
|
||||
ScriptsPane.blockDropped(sc, dx, dy);
|
||||
break;
|
||||
case 'library':
|
||||
var thumb = Palette.getHittedThumb(el, gn('spritecc'));
|
||||
ScriptsPane.blockDropped(ScratchJr.getActiveScript(), el.startx, el.starty);
|
||||
if (thumb && (gn(thumb.owner).owner.type == gn(page.currentSpriteName).owner.type)) {
|
||||
ScratchJr.storyStart('ScriptsPane.dropBlock:library');
|
||||
ScratchAudio.sndFX('copy.wav');
|
||||
Thumbs.quickHighlight(thumb);
|
||||
setTimeout(function () {
|
||||
Thumbs.quickRestore(thumb);
|
||||
}, 300);
|
||||
sc = gn(thumb.owner + '_scripts').owner;
|
||||
var strip = Project.encodeStrip(el.owner);
|
||||
var firstblock = strip[0];
|
||||
var delta = sc.gettopblocks().length * 3;
|
||||
firstblock[2] = firstblock[2] + delta;
|
||||
firstblock[3] = firstblock[3] + delta;
|
||||
sc.recreateStrip(strip);
|
||||
spr = thumb.owner;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ScratchJr.getActiveScript().owner.deleteBlocks();
|
||||
scroll.adjustCanvas();
|
||||
scroll.refresh();
|
||||
scroll.fitToScreen();
|
||||
break;
|
||||
}
|
||||
Undo.record({
|
||||
action: 'scripts',
|
||||
where: page.id,
|
||||
who: spr
|
||||
});
|
||||
ScratchJr.getActiveScript().owner.dragList = [];
|
||||
}
|
||||
|
||||
static blockDropped (sc, dx, dy) {
|
||||
Events.dragcanvas.style.zIndex = '';
|
||||
var script = ScratchJr.getActiveScript().owner;
|
||||
ScriptsPane.cleanCarets();
|
||||
script.addBlockToScripts(Events.dragcanvas, dx, dy);
|
||||
script.layout(Events.dragcanvas.owner);
|
||||
if (sc.id == ScratchJr.getActiveScript().id) {
|
||||
scroll.adjustCanvas();
|
||||
scroll.refresh();
|
||||
scroll.bounceBack();
|
||||
}
|
||||
}
|
||||
|
||||
static cleanCarets () {
|
||||
ScratchJr.getActiveScript().owner.removeCaret();
|
||||
ScriptsPane.removeLibCaret();
|
||||
}
|
||||
|
||||
static removeLibCaret () {
|
||||
for (var i = 0; i < gn('spritecc').childElementCount; i++) {
|
||||
var spr = gn('spritecc').childNodes[i];
|
||||
if (spr.nodeName == 'FORM') {
|
||||
continue;
|
||||
}
|
||||
if (thumb && (thumb.id != spr.id)) {
|
||||
Thumbs.quickRestore(spr);
|
||||
Thumbs.quickRestore(spr);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------
|
||||
// Drag Script Background
|
||||
//----------------------------------
|
||||
|
||||
static dragBackground (e) {
|
||||
if (Menu.openMenu) {
|
||||
return;
|
||||
}
|
||||
if (isTablet && e.touches && (e.touches.length > 1)) {
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
var sc = ScratchJr.getActiveScript();
|
||||
sc.top = sc.offsetTop;
|
||||
sc.left = sc.offsetLeft;
|
||||
var pt = Events.getTargetPoint(e);
|
||||
Events.dragmousex = pt.x;
|
||||
Events.dragmousey = pt.y;
|
||||
Events.dragged = false;
|
||||
ScriptsPane.setDragBackgroundEvents(ScriptsPane.dragMove, ScriptsPane.dragEnd);
|
||||
}
|
||||
|
||||
static setDragBackgroundEvents (fcnmove, fcnup) {
|
||||
if (isTablet) { // setDragBackgroundEvents
|
||||
window.ontouchmove = function (evt) {
|
||||
fcnmove(evt);
|
||||
};
|
||||
window.ontouchend = function (evt) {
|
||||
fcnup(evt);
|
||||
};
|
||||
} else {
|
||||
window.onmousemove = function (evt) {
|
||||
fcnmove(evt);
|
||||
};
|
||||
window.onmouseup = function (evt) {
|
||||
fcnup(evt);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
static dragMove (e) {
|
||||
var pt = Events.getTargetPoint(e);
|
||||
if (!Events.dragged && (Events.distance(Events.dragmousex - pt.x, Events.dragmousey - pt.y) < 5)) {
|
||||
return;
|
||||
}
|
||||
Events.dragged = true;
|
||||
var dx = pt.x - Events.dragmousex;
|
||||
var dy = pt.y - Events.dragmousey;
|
||||
Events.dragmousex = pt.x;
|
||||
Events.dragmousey = pt.y;
|
||||
Events.move3D(ScratchJr.getActiveScript(), dx, dy);
|
||||
scroll.refresh();
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
static dragEnd (e) {
|
||||
Events.dragged = false;
|
||||
e.preventDefault();
|
||||
Events.clearEvents();
|
||||
scroll.bounceBack();
|
||||
}
|
||||
|
||||
//////////////////////
|
||||
//
|
||||
//////////////////////
|
||||
|
||||
static updateScriptsPageBlocks (list) {
|
||||
for (var j = 0; j < list.length; j++) {
|
||||
if (!gn(list[j] + '_scripts')) {
|
||||
continue;
|
||||
}
|
||||
var sc = gn(list[j] + '_scripts').owner;
|
||||
if (!sc) {
|
||||
continue;
|
||||
}
|
||||
var allblocks = sc.getBlocks();
|
||||
for (var i = 0; i < allblocks.length; i++) {
|
||||
allblocks[i].updateBlock();
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ScriptsPane.removeLibCaret();
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////
|
||||
// Events MouseUP
|
||||
////////////////////////////////////////////////
|
||||
|
||||
ScriptsPane.dropBlock = function (e, el) {
|
||||
e.preventDefault();
|
||||
var sc = ScratchJr.getActiveScript();
|
||||
var spr = sc.owner.spr.id;
|
||||
var page = ScratchJr.stage.currentPage;
|
||||
switch (Palette.getLandingPlace(el, e)) {
|
||||
case 'scripts':
|
||||
var dx = localx(sc, el.left);
|
||||
var dy = localy(sc, el.top);
|
||||
ScriptsPane.blockDropped(sc, dx, dy);
|
||||
break;
|
||||
case 'library':
|
||||
var thumb = Palette.getHittedThumb(el, gn('spritecc'));
|
||||
ScriptsPane.blockDropped(ScratchJr.getActiveScript(), el.startx, el.starty);
|
||||
if (thumb && (gn(thumb.owner).owner.type == gn(page.currentSpriteName).owner.type)) {
|
||||
ScratchJr.storyStart('ScriptsPane.dropBlock:library');
|
||||
ScratchAudio.sndFX('copy.wav');
|
||||
Thumbs.quickHighlight(thumb);
|
||||
setTimeout(function () {
|
||||
Thumbs.quickRestore(thumb);
|
||||
}, 300);
|
||||
sc = gn(thumb.owner + '_scripts').owner;
|
||||
var strip = Project.encodeStrip(el.owner);
|
||||
var firstblock = strip[0];
|
||||
var delta = sc.gettopblocks().length * 3;
|
||||
firstblock[2] = firstblock[2] + delta;
|
||||
firstblock[3] = firstblock[3] + delta;
|
||||
sc.recreateStrip(strip);
|
||||
spr = thumb.owner;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ScratchJr.getActiveScript().owner.deleteBlocks();
|
||||
ScriptsPane.scroll.adjustCanvas();
|
||||
ScriptsPane.scroll.refresh();
|
||||
ScriptsPane.scroll.fitToScreen();
|
||||
break;
|
||||
}
|
||||
Undo.record({
|
||||
action: 'scripts',
|
||||
where: page.id,
|
||||
who: spr
|
||||
});
|
||||
ScratchJr.getActiveScript().owner.dragList = [];
|
||||
};
|
||||
|
||||
ScriptsPane.blockDropped = function (sc, dx, dy) {
|
||||
Events.dragcanvas.style.zIndex = '';
|
||||
var script = ScratchJr.getActiveScript().owner;
|
||||
ScriptsPane.cleanCarets();
|
||||
script.addBlockToScripts(Events.dragcanvas, dx, dy);
|
||||
script.layout(Events.dragcanvas.owner);
|
||||
if (sc.id == ScratchJr.getActiveScript().id) {
|
||||
ScriptsPane.scroll.adjustCanvas();
|
||||
ScriptsPane.scroll.refresh();
|
||||
ScriptsPane.scroll.bounceBack();
|
||||
}
|
||||
};
|
||||
|
||||
ScriptsPane.cleanCarets = function () {
|
||||
ScratchJr.getActiveScript().owner.removeCaret();
|
||||
ScriptsPane.removeLibCaret();
|
||||
};
|
||||
|
||||
ScriptsPane.removeLibCaret = function () {
|
||||
for (var i = 0; i < gn('spritecc').childElementCount; i++) {
|
||||
var spr = gn('spritecc').childNodes[i];
|
||||
if (spr.nodeName == 'FORM') {
|
||||
continue;
|
||||
}
|
||||
Thumbs.quickRestore(spr);
|
||||
}
|
||||
};
|
||||
|
||||
//----------------------------------
|
||||
// Drag Script Background
|
||||
//----------------------------------
|
||||
|
||||
ScriptsPane.dragBackground = function (e) {
|
||||
if (Menu.openMenu) {
|
||||
return;
|
||||
}
|
||||
if (isTablet && e.touches && (e.touches.length > 1)) {
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
var sc = ScratchJr.getActiveScript();
|
||||
sc.top = sc.offsetTop;
|
||||
sc.left = sc.offsetLeft;
|
||||
var pt = Events.getTargetPoint(e);
|
||||
Events.dragmousex = pt.x;
|
||||
Events.dragmousey = pt.y;
|
||||
Events.dragged = false;
|
||||
ScriptsPane.setDragBackgroundEvents(ScriptsPane.dragMove, ScriptsPane.dragEnd);
|
||||
};
|
||||
|
||||
ScriptsPane.setDragBackgroundEvents = function (fcnmove, fcnup) {
|
||||
if (isTablet) { // setDragBackgroundEvents
|
||||
window.ontouchmove = function (evt) {
|
||||
fcnmove(evt);
|
||||
};
|
||||
window.ontouchend = function (evt) {
|
||||
fcnup(evt);
|
||||
};
|
||||
} else {
|
||||
window.onmousemove = function (evt) {
|
||||
fcnmove(evt);
|
||||
};
|
||||
window.onmouseup = function (evt) {
|
||||
fcnup(evt);
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
ScriptsPane.dragMove = function (e) {
|
||||
var pt = Events.getTargetPoint(e);
|
||||
if (!Events.dragged && (Events.distance(Events.dragmousex - pt.x, Events.dragmousey - pt.y) < 5)) {
|
||||
return;
|
||||
}
|
||||
Events.dragged = true;
|
||||
var dx = pt.x - Events.dragmousex;
|
||||
var dy = pt.y - Events.dragmousey;
|
||||
Events.dragmousex = pt.x;
|
||||
Events.dragmousey = pt.y;
|
||||
Events.move3D(ScratchJr.getActiveScript(), dx, dy);
|
||||
ScriptsPane.scroll.refresh();
|
||||
e.preventDefault();
|
||||
};
|
||||
|
||||
ScriptsPane.dragEnd = function (e) {
|
||||
Events.dragged = false;
|
||||
e.preventDefault();
|
||||
Events.clearEvents();
|
||||
ScriptsPane.scroll.bounceBack();
|
||||
};
|
||||
|
||||
//////////////////////
|
||||
//
|
||||
//////////////////////
|
||||
|
||||
ScriptsPane.updateScriptsPageBlocks = function (list) {
|
||||
for (var j = 0; j < list.length; j++) {
|
||||
if (!gn(list[j] + '_scripts')) {
|
||||
continue;
|
||||
}
|
||||
var sc = gn(list[j] + '_scripts').owner;
|
||||
if (!sc) {
|
||||
continue;
|
||||
}
|
||||
var allblocks = sc.getBlocks();
|
||||
for (var i = 0; i < allblocks.length; i++) {
|
||||
allblocks[i].updateBlock();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
2074
src/editor/ui/UI.js
2074
src/editor/ui/UI.js
File diff suppressed because it is too large
Load diff
|
@ -1,423 +1,431 @@
|
|||
//////////////////////////////////
|
||||
// Undo / Redo Functions
|
||||
//////////////////////////////////
|
||||
var Undo = function () {};
|
||||
|
||||
Undo.buffer = [];
|
||||
Undo.index = 0;
|
||||
Undo.aux = '';
|
||||
Undo.tryCounter;
|
||||
import ScratchJr from '../ScratchJr';
|
||||
import Thumbs from './Thumbs';
|
||||
import Project from './Project';
|
||||
import Palette from './Palette';
|
||||
import UI from './UI';
|
||||
import ScratchAudio from '../../utils/ScratchAudio';
|
||||
import {newHTML, isTablet, gn} from '../../utils/lib';
|
||||
|
||||
Undo.init = function () {
|
||||
Undo.index = Undo.buffer.length;
|
||||
Undo.update();
|
||||
};
|
||||
let buffer = [];
|
||||
let index = 0;
|
||||
let tryCounter;
|
||||
|
||||
Undo.setup = function (p) {
|
||||
var div = newHTML('div', 'controlundo', p);
|
||||
div.setAttribute('id', 'undocontrols');
|
||||
var lib = [['undo', Undo.prevStep], ['redo', Undo.nextStep]];
|
||||
for (var i = 0; i < lib.length; i++) {
|
||||
Undo.newToggleClicky(div, 'id_', lib[i][0], lib[i][1]);
|
||||
export default class Undo {
|
||||
static init () {
|
||||
index = buffer.length;
|
||||
Undo.update();
|
||||
}
|
||||
Undo.update();
|
||||
};
|
||||
|
||||
Undo.newToggleClicky = function (p, prefix, key, fcn) {
|
||||
var div = newHTML('div', key + 'button', p);
|
||||
div.setAttribute('type', 'toggleclicky');
|
||||
div.setAttribute('id', prefix + key);
|
||||
if (fcn) {
|
||||
if (isTablet) {
|
||||
div.ontouchstart = function (evt) {
|
||||
fcn(evt);
|
||||
};
|
||||
} else {
|
||||
div.onmousedown = function (evt) {
|
||||
fcn(evt);
|
||||
};
|
||||
static setup (p) {
|
||||
var div = newHTML('div', 'controlundo', p);
|
||||
div.setAttribute('id', 'undocontrols');
|
||||
var lib = [['undo', Undo.prevStep], ['redo', Undo.nextStep]];
|
||||
for (var i = 0; i < lib.length; i++) {
|
||||
Undo.newToggleClicky(div, 'id_', lib[i][0], lib[i][1]);
|
||||
}
|
||||
Undo.update();
|
||||
}
|
||||
return div;
|
||||
};
|
||||
|
||||
Undo.record = function (obj) {
|
||||
//console.log ("record", Undo.index, JSON.stringify(obj));
|
||||
if (ScratchJr.getActiveScript()) {
|
||||
ScratchJr.getActiveScript().owner.removeCaret();
|
||||
}
|
||||
if ((Undo.index + 1) <= Undo.buffer.length) {
|
||||
Undo.buffer.splice(Undo.index + 1, Undo.buffer.length);
|
||||
}
|
||||
var data = Project.getUndo();
|
||||
for (var key in obj) {
|
||||
data[key] = obj[key];
|
||||
}
|
||||
Undo.buffer.push(data);
|
||||
Undo.index++;
|
||||
Undo.update();
|
||||
|
||||
// Project change state is usually tracked by looking if a particular action would record an undo
|
||||
// We need slightly more specific behavior for story starters, so storyStarted is unaffected here.
|
||||
ScratchJr.changed = true;
|
||||
};
|
||||
|
||||
//////////////////////////////////
|
||||
// Control buttons callbacks
|
||||
//
|
||||
////////////////////////////////
|
||||
|
||||
Undo.prevStep = function (e) {
|
||||
if (isTablet && e.touches && (e.touches.length > 1)) {
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
ScratchJr.unfocus();
|
||||
ScratchJr.time = e.timeStamp;
|
||||
while (Undo.index >= Undo.buffer.length) {
|
||||
Undo.index--;
|
||||
}
|
||||
Undo.index--;
|
||||
var snd = (Undo.index < 0) ? 'boing.wav' : 'tap.wav';
|
||||
ScratchAudio.sndFX(snd);
|
||||
if (Undo.index < 0) {
|
||||
Undo.index = 0;
|
||||
} else {
|
||||
Undo.smartRecreate('prev', Undo.buffer[Undo.index + 1], Undo.buffer[Undo.index]);
|
||||
}
|
||||
};
|
||||
|
||||
Undo.nextStep = function (e) {
|
||||
if (isTablet && e.touches && (e.touches.length > 1)) {
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
ScratchJr.unfocus();
|
||||
ScratchJr.time = e.timeStamp;
|
||||
Undo.index++;
|
||||
var snd = (Undo.index > Undo.buffer.length - 1) ? 'boing.wav' : 'tap.wav';
|
||||
ScratchAudio.sndFX(snd);
|
||||
if (Undo.index > Undo.buffer.length - 1) {
|
||||
Undo.index = Undo.buffer.length - 1;
|
||||
} else {
|
||||
Undo.smartRecreate('next', Undo.buffer[Undo.index], Undo.buffer[Undo.index]);
|
||||
}
|
||||
};
|
||||
|
||||
Undo.smartRecreate = function (cmd, elem, data) {
|
||||
ScratchJr.stopStrips();
|
||||
var action = elem.action;
|
||||
var page = elem.where;
|
||||
var spr = elem.who;
|
||||
// console.log (action, page, spr);
|
||||
switch (action) {
|
||||
case 'pageorder':
|
||||
ScratchJr.stage.pages = Undo.getPageOrder(data);
|
||||
Undo.recreateAllScripts(data);
|
||||
ScratchJr.stage.setPage(gn(data.currentPage).owner, false);
|
||||
if (Palette.numcat == 5) {
|
||||
Palette.selectCategory(5);
|
||||
}
|
||||
break;
|
||||
case 'changepage':
|
||||
ScratchJr.stage.setPage(gn(data.currentPage).owner, false);
|
||||
break;
|
||||
case 'changebkg':
|
||||
gn(page).owner.redoChangeBkg(data);
|
||||
break;
|
||||
case 'scripts':
|
||||
Undo.redoScripts(data, page, spr);
|
||||
if (spr && gn(spr)) {
|
||||
gn(page).owner.setCurrentSprite(gn(spr).owner); // sets the variables
|
||||
Thumbs.selectThisSprite(gn(spr).owner); // sets the UI
|
||||
UI.resetSpriteLibrary();
|
||||
}
|
||||
break;
|
||||
case 'deletepage':
|
||||
case 'addpage':
|
||||
if (data[page]) {
|
||||
Undo.copyPage(data, page);
|
||||
} else {
|
||||
Undo.removePage(data, page);
|
||||
}
|
||||
break;
|
||||
case 'deletesprite':
|
||||
case 'copy':
|
||||
if (data[page][spr]) {
|
||||
Undo.copySprite(data, page, spr);
|
||||
} else {
|
||||
Undo.removeSprite(data, page, spr);
|
||||
}
|
||||
break;
|
||||
case 'deletesound':
|
||||
var sounds = data[page][spr].sounds.concat();
|
||||
gn(spr).owner.sounds = sounds;
|
||||
Undo.redoScripts(data, page, spr);
|
||||
if (Palette.numcat == 3) {
|
||||
Palette.selectCategory(3);
|
||||
}
|
||||
break;
|
||||
case 'recordsound':
|
||||
spr = gn((data[page][spr]).id).owner;
|
||||
if (elem.sound && (spr.sounds.indexOf(elem.sound) > -1)) {
|
||||
var indx = spr.sounds.indexOf(elem.sound);
|
||||
if (indx > -1) {
|
||||
spr.sounds.splice(indx, 1);
|
||||
static newToggleClicky (p, prefix, key, fcn) {
|
||||
var div = newHTML('div', key + 'button', p);
|
||||
div.setAttribute('type', 'toggleclicky');
|
||||
div.setAttribute('id', prefix + key);
|
||||
if (fcn) {
|
||||
if (isTablet) {
|
||||
div.ontouchstart = function (evt) {
|
||||
fcn(evt);
|
||||
};
|
||||
} else {
|
||||
div.onmousedown = function (evt) {
|
||||
fcn(evt);
|
||||
};
|
||||
}
|
||||
} else {
|
||||
spr.sounds.push(elem.sound);
|
||||
}
|
||||
if (Palette.numcat == 3) {
|
||||
Palette.selectCategory(3);
|
||||
}
|
||||
break;
|
||||
case 'edittext': // sprite delete or add
|
||||
case 'modify':
|
||||
Undo.removeSprite(data, page, spr);
|
||||
if (data[page][spr]) {
|
||||
Undo.copySprite(data, page, spr);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Project.clear();
|
||||
Undo.recreate(Undo.buffer[Undo.index]);
|
||||
break;
|
||||
return div;
|
||||
}
|
||||
Undo.update();
|
||||
};
|
||||
|
||||
Undo.copyPage = function (obj, page) {
|
||||
var sc = ScratchJr.getSprite() ? gn(ScratchJr.stage.currentPage.currentSpriteName + '_scripts') : undefined;
|
||||
if (sc) {
|
||||
sc.owner.deactivate();
|
||||
static record (obj) {
|
||||
//console.log ("record", index, JSON.stringify(obj));
|
||||
if (ScratchJr.getActiveScript()) {
|
||||
ScratchJr.getActiveScript().owner.removeCaret();
|
||||
}
|
||||
if ((index + 1) <= buffer.length) {
|
||||
buffer.splice(index + 1, buffer.length);
|
||||
}
|
||||
var data = Project.getUndo();
|
||||
for (var key in obj) {
|
||||
data[key] = obj[key];
|
||||
}
|
||||
buffer.push(data);
|
||||
index++;
|
||||
Undo.update();
|
||||
|
||||
// Project change state is usually tracked by looking if a particular action would record an undo
|
||||
// We need slightly more specific behavior for story starters, so storyStarted is unaffected here.
|
||||
ScratchJr.changed = true;
|
||||
}
|
||||
Project.recreatePage(page, obj[page], nextStep2);
|
||||
function nextStep2 () {
|
||||
ScratchJr.stage.pages = Undo.getPageOrder(obj);
|
||||
ScratchJr.stage.setPage(gn(obj.currentPage).owner, false);
|
||||
Undo.recreateAllScripts(obj);
|
||||
var spritename = obj[obj.currentPage].lastSprite;
|
||||
if (spritename && gn(spritename)) {
|
||||
var spr = gn(spritename).owner;
|
||||
var page = spr.div.parentNode.owner;
|
||||
page.setCurrentSprite(spr);
|
||||
Thumbs.selectThisSprite(spr);
|
||||
|
||||
//////////////////////////////////
|
||||
// Control buttons callbacks
|
||||
//
|
||||
////////////////////////////////
|
||||
|
||||
static prevStep (e) {
|
||||
if (isTablet && e.touches && (e.touches.length > 1)) {
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
ScratchJr.unfocus();
|
||||
ScratchJr.time = e.timeStamp;
|
||||
while (index >= buffer.length) {
|
||||
index--;
|
||||
}
|
||||
index--;
|
||||
var snd = (index < 0) ? 'boing.wav' : 'tap.wav';
|
||||
ScratchAudio.sndFX(snd);
|
||||
if (index < 0) {
|
||||
index = 0;
|
||||
} else {
|
||||
Undo.smartRecreate('prev', buffer[index + 1], buffer[index]);
|
||||
}
|
||||
}
|
||||
|
||||
static nextStep (e) {
|
||||
if (isTablet && e.touches && (e.touches.length > 1)) {
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
ScratchJr.unfocus();
|
||||
ScratchJr.time = e.timeStamp;
|
||||
index++;
|
||||
var snd = (index > buffer.length - 1) ? 'boing.wav' : 'tap.wav';
|
||||
ScratchAudio.sndFX(snd);
|
||||
if (index > buffer.length - 1) {
|
||||
index = buffer.length - 1;
|
||||
} else {
|
||||
Undo.smartRecreate('next', buffer[index], buffer[index]);
|
||||
}
|
||||
}
|
||||
|
||||
static smartRecreate (cmd, elem, data) {
|
||||
ScratchJr.stopStrips();
|
||||
var action = elem.action;
|
||||
var page = elem.where;
|
||||
var spr = elem.who;
|
||||
// console.log (action, page, spr);
|
||||
switch (action) {
|
||||
case 'pageorder':
|
||||
ScratchJr.stage.pages = Undo.getPageOrder(data);
|
||||
Undo.recreateAllScripts(data);
|
||||
ScratchJr.stage.setPage(gn(data.currentPage).owner, false);
|
||||
if (Palette.numcat == 5) {
|
||||
Palette.selectCategory(5);
|
||||
}
|
||||
break;
|
||||
case 'changepage':
|
||||
ScratchJr.stage.setPage(gn(data.currentPage).owner, false);
|
||||
break;
|
||||
case 'changebkg':
|
||||
gn(page).owner.redoChangeBkg(data);
|
||||
break;
|
||||
case 'scripts':
|
||||
Undo.redoScripts(data, page, spr);
|
||||
if (spr && gn(spr)) {
|
||||
gn(page).owner.setCurrentSprite(gn(spr).owner); // sets the variables
|
||||
Thumbs.selectThisSprite(gn(spr).owner); // sets the UI
|
||||
UI.resetSpriteLibrary();
|
||||
}
|
||||
break;
|
||||
case 'deletepage':
|
||||
case 'addpage':
|
||||
if (data[page]) {
|
||||
Undo.copyPage(data, page);
|
||||
} else {
|
||||
Undo.removePage(data, page);
|
||||
}
|
||||
break;
|
||||
case 'deletesprite':
|
||||
case 'copy':
|
||||
if (data[page][spr]) {
|
||||
Undo.copySprite(data, page, spr);
|
||||
} else {
|
||||
Undo.removeSprite(data, page, spr);
|
||||
}
|
||||
break;
|
||||
case 'deletesound':
|
||||
var sounds = data[page][spr].sounds.concat();
|
||||
gn(spr).owner.sounds = sounds;
|
||||
Undo.redoScripts(data, page, spr);
|
||||
if (Palette.numcat == 3) {
|
||||
Palette.selectCategory(3);
|
||||
}
|
||||
break;
|
||||
case 'recordsound':
|
||||
spr = gn((data[page][spr]).id).owner;
|
||||
if (elem.sound && (spr.sounds.indexOf(elem.sound) > -1)) {
|
||||
var indx = spr.sounds.indexOf(elem.sound);
|
||||
if (indx > -1) {
|
||||
spr.sounds.splice(indx, 1);
|
||||
}
|
||||
} else {
|
||||
spr.sounds.push(elem.sound);
|
||||
}
|
||||
if (Palette.numcat == 3) {
|
||||
Palette.selectCategory(3);
|
||||
}
|
||||
break;
|
||||
case 'edittext': // sprite delete or add
|
||||
case 'modify':
|
||||
Undo.removeSprite(data, page, spr);
|
||||
if (data[page][spr]) {
|
||||
Undo.copySprite(data, page, spr);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Project.clear();
|
||||
Undo.recreate(buffer[index]);
|
||||
break;
|
||||
}
|
||||
Undo.update();
|
||||
}
|
||||
|
||||
static copyPage (obj, page) {
|
||||
var sc = ScratchJr.getSprite() ? gn(ScratchJr.stage.currentPage.currentSpriteName + '_scripts') : undefined;
|
||||
if (sc) {
|
||||
sc.owner.deactivate();
|
||||
}
|
||||
Project.recreatePage(page, obj[page], nextStep2);
|
||||
function nextStep2 () {
|
||||
ScratchJr.stage.pages = Undo.getPageOrder(obj);
|
||||
ScratchJr.stage.setPage(gn(obj.currentPage).owner, false);
|
||||
Undo.recreateAllScripts(obj);
|
||||
var spritename = obj[obj.currentPage].lastSprite;
|
||||
if (spritename && gn(spritename)) {
|
||||
var spr = gn(spritename).owner;
|
||||
var page = spr.div.parentNode.owner;
|
||||
page.setCurrentSprite(spr);
|
||||
Thumbs.selectThisSprite(spr);
|
||||
if (Palette.numcat == 5) {
|
||||
Palette.selectCategory(5);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Undo.getPageOrder = function (data) {
|
||||
var pages = data.pages;
|
||||
var res = [];
|
||||
for (var i = 0; i < pages.length; i++) {
|
||||
res.push(gn(pages[i]).owner);
|
||||
static getPageOrder (data) {
|
||||
var pages = data.pages;
|
||||
var res = [];
|
||||
for (var i = 0; i < pages.length; i++) {
|
||||
res.push(gn(pages[i]).owner);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
Undo.recreateAllScripts = function (data) {
|
||||
for (var n = 0; n < data.pages.length; n++) {
|
||||
var page = data[data.pages[n]];
|
||||
var sprnames = page.sprites;
|
||||
for (var i = 0; i < sprnames.length; i++) {
|
||||
var spr = page[sprnames[i]];
|
||||
if (!spr) {
|
||||
continue;
|
||||
static recreateAllScripts (data) {
|
||||
for (var n = 0; n < data.pages.length; n++) {
|
||||
var page = data[data.pages[n]];
|
||||
var sprnames = page.sprites;
|
||||
for (var i = 0; i < sprnames.length; i++) {
|
||||
var spr = page[sprnames[i]];
|
||||
if (!spr) {
|
||||
continue;
|
||||
}
|
||||
if (spr.type != 'sprite') {
|
||||
continue;
|
||||
}
|
||||
var sc = gn(spr.id + '_scripts');
|
||||
if (!sc) {
|
||||
continue;
|
||||
}
|
||||
Undo.redoScripts(data, data.pages[n], sprnames[i]);
|
||||
}
|
||||
if (spr.type != 'sprite') {
|
||||
continue;
|
||||
}
|
||||
var sc = gn(spr.id + '_scripts');
|
||||
if (!sc) {
|
||||
continue;
|
||||
}
|
||||
Undo.redoScripts(data, data.pages[n], sprnames[i]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Undo.removePage = function (data, str) {
|
||||
if (!gn(str)) {
|
||||
return;
|
||||
}
|
||||
var page = gn(str).owner;
|
||||
if (!page) {
|
||||
return;
|
||||
}
|
||||
ScratchJr.stage.removePageBlocks(str);
|
||||
ScratchJr.stage.removePage(page);
|
||||
ScratchJr.stage.pages = Undo.getPageOrder(data);
|
||||
if (ScratchJr.stage.pages.length == 0) {
|
||||
Undo.copyPage(data, data.currentPage);
|
||||
} else {
|
||||
ScratchJr.stage.setViewPage(gn(data.currentPage).owner);
|
||||
Thumbs.updateSprites();
|
||||
Thumbs.updatePages();
|
||||
}
|
||||
};
|
||||
|
||||
Undo.redoScripts = function (data, page, spr) {
|
||||
var div = gn(spr + '_scripts');
|
||||
while (div.childElementCount > 0) {
|
||||
div.removeChild(div.childNodes[0]);
|
||||
}
|
||||
var sc = div.owner;
|
||||
var list = data[page][spr].scripts;
|
||||
for (var j = 0; j < list.length; j++) {
|
||||
sc.recreateStrip(list[j]);
|
||||
}
|
||||
};
|
||||
|
||||
Undo.copySprite = function (data, page, spr) {
|
||||
var obj = data[page][spr];
|
||||
var fcn = function (spr) {
|
||||
if (spr.type == 'sprite') {
|
||||
if (page == ScratchJr.stage.currentPage.id) {
|
||||
spr.div.style.visibility = 'visible';
|
||||
}
|
||||
Undo.setSprite(page, data);
|
||||
static removePage (data, str) {
|
||||
if (!gn(str)) {
|
||||
return;
|
||||
}
|
||||
var page = gn(str).owner;
|
||||
if (!page) {
|
||||
return;
|
||||
}
|
||||
ScratchJr.stage.removePageBlocks(str);
|
||||
ScratchJr.stage.removePage(page);
|
||||
ScratchJr.stage.pages = Undo.getPageOrder(data);
|
||||
if (ScratchJr.stage.pages.length == 0) {
|
||||
Undo.copyPage(data, data.currentPage);
|
||||
} else {
|
||||
var delta = spr.fontsize * 1.35;
|
||||
if (spr.homey == spr.page.textstartat) {
|
||||
spr.page.textstartat += delta;
|
||||
}
|
||||
ScratchJr.stage.setViewPage(gn(data.currentPage).owner);
|
||||
Thumbs.updateSprites();
|
||||
Thumbs.updatePages();
|
||||
}
|
||||
};
|
||||
Project.recreateObject(gn(page).owner, spr, obj, fcn, (data[page].lastSprite == spr));
|
||||
};
|
||||
}
|
||||
|
||||
Undo.setSprite = function (page, data) {
|
||||
Thumbs.updatePages();
|
||||
if (page != ScratchJr.stage.currentPage.id) {
|
||||
return;
|
||||
static redoScripts (data, page, spr) {
|
||||
var div = gn(spr + '_scripts');
|
||||
while (div.childElementCount > 0) {
|
||||
div.removeChild(div.childNodes[0]);
|
||||
}
|
||||
var sc = div.owner;
|
||||
var list = data[page][spr].scripts;
|
||||
for (var j = 0; j < list.length; j++) {
|
||||
sc.recreateStrip(list[j]);
|
||||
}
|
||||
}
|
||||
var pageobj = gn(page).owner;
|
||||
var lastspritename = data[page].lastSprite;
|
||||
var lastsprite = lastspritename ? gn(lastspritename) : undefined;
|
||||
if (!lastsprite) {
|
||||
pageobj.setCurrentSprite(undefined);
|
||||
} else {
|
||||
var cs = lastsprite.owner;
|
||||
pageobj.setCurrentSprite(cs);
|
||||
UI.needsScroll();
|
||||
Thumbs.updateSprites();
|
||||
}
|
||||
};
|
||||
|
||||
Undo.removeSprite = function (data, page, spr) {
|
||||
if (!gn(spr)) {
|
||||
return;
|
||||
static copySprite (data, page, spr) {
|
||||
var obj = data[page][spr];
|
||||
var fcn = function (spr) {
|
||||
if (spr.type == 'sprite') {
|
||||
if (page == ScratchJr.stage.currentPage.id) {
|
||||
spr.div.style.visibility = 'visible';
|
||||
}
|
||||
Undo.setSprite(page, data);
|
||||
} else {
|
||||
var delta = spr.fontsize * 1.35;
|
||||
if (spr.homey == spr.page.textstartat) {
|
||||
spr.page.textstartat += delta;
|
||||
}
|
||||
Thumbs.updatePages();
|
||||
}
|
||||
};
|
||||
Project.recreateObject(gn(page).owner, spr, obj, fcn, (data[page].lastSprite == spr));
|
||||
}
|
||||
var sprite = gn(spr).owner;
|
||||
var th = sprite.thumbnail;
|
||||
ScratchJr.runtime.stopThreadSprite(sprite);
|
||||
var pageobj = gn(page).owner;
|
||||
var list = JSON.parse(pageobj.sprites);
|
||||
var n = list.indexOf(spr);
|
||||
list.splice(n, 1);
|
||||
pageobj.sprites = JSON.stringify(list);
|
||||
gn(spr).parentNode.removeChild(gn(spr));
|
||||
if (!gn(spr + '_scripts')) {
|
||||
|
||||
static setSprite (page, data) {
|
||||
Thumbs.updatePages();
|
||||
return;
|
||||
}
|
||||
var sc = gn(spr + '_scripts');
|
||||
if (sc) {
|
||||
sc.parentNode.removeChild(sc);
|
||||
}
|
||||
if (th && th.parentNode) {
|
||||
th.parentNode.removeChild(th);
|
||||
}
|
||||
Undo.setSprite(page, data);
|
||||
};
|
||||
|
||||
Undo.recreate = function (data) {
|
||||
Project.mediaCount = 0;
|
||||
ScratchJr.stage.pages = [];
|
||||
var pages = data.pages;
|
||||
if (data.projectsounds) {
|
||||
ScratchAudio.projectsounds = data.projectsounds;
|
||||
}
|
||||
for (var i = 0; i < pages.length; i++) {
|
||||
Project.recreatePage(pages[i], data[pages[i]]);
|
||||
}
|
||||
Undo.loadPage(data.currentPage);
|
||||
};
|
||||
|
||||
Undo.loadPage = function (pageid) {
|
||||
var pages = ScratchJr.stage.getPagesID();
|
||||
if (pages.indexOf(pageid) < 0) {
|
||||
ScratchJr.stage.currentPage = ScratchJr.stage.pages[0];
|
||||
} else {
|
||||
ScratchJr.stage.currentPage = ScratchJr.stage.getPage(pageid);
|
||||
}
|
||||
ScratchJr.stage.currentPage.div.style.visibility = 'visible';
|
||||
ScratchJr.stage.currentPage.setPageSprites('visible');
|
||||
Undo.tryCounter = 100;
|
||||
if (Project.mediaCount > 0) {
|
||||
setTimeout(function () {
|
||||
Undo.updateImages();
|
||||
}, 20);
|
||||
} else {
|
||||
Undo.doneLoading();
|
||||
}
|
||||
};
|
||||
|
||||
Undo.updateImages = function () {
|
||||
Undo.tryCounter--;
|
||||
var done = (Project.mediaCount < 1) || (Undo.tryCounter < 1);
|
||||
if (done) {
|
||||
Undo.doneLoading();
|
||||
} else {
|
||||
setTimeout(function () {
|
||||
Undo.updateImages();
|
||||
}, 20);
|
||||
}
|
||||
};
|
||||
|
||||
Undo.flashIcon = function (div, press) {
|
||||
div.setAttribute('class', press);
|
||||
setTimeout(function () {
|
||||
Undo.update();
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
Undo.doneLoading = function () {
|
||||
Thumbs.updateSprites();
|
||||
Thumbs.updatePages();
|
||||
};
|
||||
|
||||
Undo.update = function () {
|
||||
if (gn('id_undo')) {
|
||||
if (Undo.buffer.length == 1) {
|
||||
Undo.tunOffButton(gn('id_undo'));
|
||||
if (page != ScratchJr.stage.currentPage.id) {
|
||||
return;
|
||||
}
|
||||
var pageobj = gn(page).owner;
|
||||
var lastspritename = data[page].lastSprite;
|
||||
var lastsprite = lastspritename ? gn(lastspritename) : undefined;
|
||||
if (!lastsprite) {
|
||||
pageobj.setCurrentSprite(undefined);
|
||||
} else {
|
||||
if (Undo.index < 1) {
|
||||
var cs = lastsprite.owner;
|
||||
pageobj.setCurrentSprite(cs);
|
||||
UI.needsScroll();
|
||||
Thumbs.updateSprites();
|
||||
}
|
||||
}
|
||||
|
||||
static removeSprite (data, page, spr) {
|
||||
if (!gn(spr)) {
|
||||
return;
|
||||
}
|
||||
var sprite = gn(spr).owner;
|
||||
var th = sprite.thumbnail;
|
||||
ScratchJr.runtime.stopThreadSprite(sprite);
|
||||
var pageobj = gn(page).owner;
|
||||
var list = JSON.parse(pageobj.sprites);
|
||||
var n = list.indexOf(spr);
|
||||
list.splice(n, 1);
|
||||
pageobj.sprites = JSON.stringify(list);
|
||||
gn(spr).parentNode.removeChild(gn(spr));
|
||||
if (!gn(spr + '_scripts')) {
|
||||
Thumbs.updatePages();
|
||||
return;
|
||||
}
|
||||
var sc = gn(spr + '_scripts');
|
||||
if (sc) {
|
||||
sc.parentNode.removeChild(sc);
|
||||
}
|
||||
if (th && th.parentNode) {
|
||||
th.parentNode.removeChild(th);
|
||||
}
|
||||
Undo.setSprite(page, data);
|
||||
}
|
||||
|
||||
static recreate (data) {
|
||||
Project.mediaCount = 0;
|
||||
ScratchJr.stage.pages = [];
|
||||
var pages = data.pages;
|
||||
if (data.projectsounds) {
|
||||
ScratchAudio.projectsounds = data.projectsounds;
|
||||
}
|
||||
for (var i = 0; i < pages.length; i++) {
|
||||
Project.recreatePage(pages[i], data[pages[i]]);
|
||||
}
|
||||
Undo.loadPage(data.currentPage);
|
||||
}
|
||||
|
||||
static loadPage (pageid) {
|
||||
var pages = ScratchJr.stage.getPagesID();
|
||||
if (pages.indexOf(pageid) < 0) {
|
||||
ScratchJr.stage.currentPage = ScratchJr.stage.pages[0];
|
||||
} else {
|
||||
ScratchJr.stage.currentPage = ScratchJr.stage.getPage(pageid);
|
||||
}
|
||||
ScratchJr.stage.currentPage.div.style.visibility = 'visible';
|
||||
ScratchJr.stage.currentPage.setPageSprites('visible');
|
||||
tryCounter = 100;
|
||||
if (Project.mediaCount > 0) {
|
||||
setTimeout(function () {
|
||||
Undo.updateImages();
|
||||
}, 20);
|
||||
} else {
|
||||
Undo.doneLoading();
|
||||
}
|
||||
}
|
||||
|
||||
static updateImages () {
|
||||
tryCounter--;
|
||||
var done = (Project.mediaCount < 1) || (tryCounter < 1);
|
||||
if (done) {
|
||||
Undo.doneLoading();
|
||||
} else {
|
||||
setTimeout(function () {
|
||||
Undo.updateImages();
|
||||
}, 20);
|
||||
}
|
||||
}
|
||||
|
||||
static flashIcon (div, press) {
|
||||
div.setAttribute('class', press);
|
||||
setTimeout(function () {
|
||||
Undo.update();
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
static doneLoading () {
|
||||
Thumbs.updateSprites();
|
||||
Thumbs.updatePages();
|
||||
}
|
||||
|
||||
static update () {
|
||||
if (gn('id_undo')) {
|
||||
if (buffer.length == 1) {
|
||||
Undo.tunOffButton(gn('id_undo'));
|
||||
} else {
|
||||
Undo.tunOnButton(gn('id_undo'));
|
||||
if (index < 1) {
|
||||
Undo.tunOffButton(gn('id_undo'));
|
||||
} else {
|
||||
Undo.tunOnButton(gn('id_undo'));
|
||||
}
|
||||
}
|
||||
if (index >= buffer.length - 1) {
|
||||
Undo.tunOffButton(gn('id_redo'));
|
||||
} else {
|
||||
Undo.tunOnButton(gn('id_redo'));
|
||||
}
|
||||
}
|
||||
if (Undo.index >= Undo.buffer.length - 1) {
|
||||
Undo.tunOffButton(gn('id_redo'));
|
||||
} else {
|
||||
Undo.tunOnButton(gn('id_redo'));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Undo.tunOnButton = function (kid) {
|
||||
var kclass = kid.getAttribute('class').split(' ')[0];
|
||||
kid.setAttribute('class', kclass + ' enable');
|
||||
};
|
||||
static tunOnButton (kid) {
|
||||
var kclass = kid.getAttribute('class').split(' ')[0];
|
||||
kid.setAttribute('class', kclass + ' enable');
|
||||
}
|
||||
|
||||
Undo.tunOffButton = function (kid) {
|
||||
var kclass = kid.getAttribute('class').split(' ')[0];
|
||||
kid.setAttribute('class', kclass + ' disable');
|
||||
};
|
||||
static tunOffButton (kid) {
|
||||
var kclass = kid.getAttribute('class').split(' ')[0];
|
||||
kid.setAttribute('class', kclass + ' disable');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -626,7 +626,6 @@ export default class Paint {
|
|||
ti.getBoundingClientRect().bottom * window.devicePixelRatio
|
||||
);
|
||||
}
|
||||
Undo.aux = Project.getProject(ScratchJr.stage.currentPage.id);
|
||||
setTimeout(function () {
|
||||
ti.setSelectionRange(ti.value.length, ti.value.length);
|
||||
}, 1);
|
||||
|
|
Loading…
Reference in a new issue