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