not really known
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

1047 lines
32 KiB

// Copyright (c) 2014-16 Walter Bender
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the The GNU Affero General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// You should have received a copy of the GNU Affero General Public
// License along with this library; if not, write to the Free Software
// Foundation, 51 Franklin Street, Suite 500 Boston, MA 02110-1335 USA
//The ProtoBlock class is defined in this file. Protoblocks are the prototypes
//from which Blocks are created.
// Protoblock contain generic information about blocks and some
// methods common to all blocks.
function ProtoBlock(name) {
// Name is used run-dictionary index, and palette label.
this.name = name;
// The palette to which this block is assigned.
this.palette = null;
// The graphic style used by the block.
this.style = null;
// The generator function used to create the artwork
this.generator = null;
// Does the block expand (or collapse) when other blocks are
// attached? e.g., start, repeat...
this.expandable = false;
// Is this block a parameter? Parameters have their labels
// overwritten with their current value.
this.parameter = false;
// How many "non-flow" arguments does a block have? (flow is
// vertical down a stack; args are horizontal. The pendown block
// has 0 args; the forward block has 1 arg; the setxy block has 2
// args.
this.args = 0;
// Default values for block parameters, e.g., forward 100 or right 90.
this.defaults = [];
// What is the size of the block prior to any expansion?
this.size = 1.0;
// Dock types are a list of the types associated with the docking points.
this.dockTypes = [];
// Static labels are generated as part of the inline SVG.
this.staticLabels = [];
// Default fontsize used for static labels.
this.fontsize = null;
// Extra block width for long labels
this.extraWidth = 0;
// Block scale
this.scale = DEFAULTBLOCKSCALE;
// The filepath of the image.
this.image = null;
// Hidden: don't show on any palette
this.hidden = false;
// Disabled: use inactive colors
this.disabled = false;
//Stores the width of the text component
this.textWidth = 0;
this.adjustWidthToLabel = function () {
if (this.staticLabels.length === 0) {
return;
}
var c = new createjs.Container();
var text = new createjs.Text(this.staticLabels[0], this.fontSize + 'px Sans', '#000000');
c.addChild(text);
var b = c.getBounds();
this.textWidth = b.width;
this.extraWidth += Math.max(b.width - 30, 0);
};
// What follows are the initializations for different block
// styles.
// E.g., penup, pendown
this.zeroArgBlock = function () {
this.args = 0;
this.dockTypes.push('out');
this.dockTypes.push('in');
this.generator = this.zeroArgBlockGenerator;
};
this.zeroArgBlockGenerator = function () {
var svg = new SVG();
svg.init();
svg.setScale(this.scale);
svg.setTab(true);
svg.setSlot(true);
if (this.fontsize) {
svg.setFontSize(this.fontsize);
}
svg.setExpand(30 + this.extraWidth, 0, 0, 0);
var artwork = svg.basicBlock();
return [artwork, svg.docks];
};
// E.g., hidden (used at end of clamp)
this.hiddenBlockFlow = function () {
this.args = 0;
this.size = 0;
this.dockTypes.push('out');
this.dockTypes.push('in');
this.generator = this.hiddenBlockFlowGenerator;
};
// E.g., hidden (used at end of no flow clamp)
this.hiddenBlockNoFlow = function () {
this.args = 0;
this.size = 0;
this.dockTypes.push('out');
this.dockTypes.push('unavailable');
this.generator = this.hiddenBlockFlowGenerator;
};
this.hiddenBlockFlowGenerator = function () {
var svg = new SVG();
svg.init();
svg.setScale(this.scale);
svg.setSlot(true);
svg.setTab(true);
if (this.fontsize) {
svg.setFontSize(this.fontsize);
}
// We need to generate the artwork in order to generate the dock.
var artwork = svg.basicBlock();
// Then we replace the artwork with a single pixel.
var artwork = '<svg xmlns="http://www.w3.org/2000/svg" width="1" height="1"><text style="font-size:10px;fill:#000000;font-family:sans-serif;text-anchor:end"><tspan x="46.333333333333336" y="13.5">block_label</tspan></text></svg>';
// And bring the last dock position to the top.
svg.docks[1][1] = svg.docks[0][1];
return [artwork, svg.docks];
};
// E.g., break
this.basicBlockNoFlow = function () {
this.args = 0;
this.dockTypes.push('out');
this.dockTypes.push('unavailable');
this.generator = this.basicBlockNoFlowGenerator;
};
this.basicBlockNoFlowGenerator = function () {
var svg = new SVG();
svg.init();
svg.setScale(this.scale);
svg.setSlot(true);
svg.setTail(true);
if (this.fontsize) {
svg.setFontSize(this.fontsize);
}
svg.setExpand(30 + this.extraWidth, 0, 0, 0);
var artwork = svg.basicBlock();
return [artwork, svg.docks];
};
// E.g., collapsed
this.basicBlockCollapsed = function () {
this.args = 0;
this.dockTypes.push('unavailable');
this.dockTypes.push('unavailable');
this.generator = this.basicBlockCollapsedGenerator;
};
this.basicBlockCollapsedGenerator = function () {
var svg = new SVG();
svg.init();
svg.setScale(this.scale);
svg.setCap(true);
svg.setTail(true);
if (this.fontsize) {
svg.setFontSize(this.fontsize);
}
svg.setExpand(30 + this.extraWidth, 0, 0, 0);
var artwork = svg.basicBlock();
return [artwork, svg.docks];
};
// E.g., forward, right
this.oneArgBlock = function () {
this.args = 1;
this.dockTypes.push('out');
this.dockTypes.push('numberin');
this.dockTypes.push('in');
this.generator = this.oneArgBlockGenerator;
};
this.oneArgBlockGenerator = function () {
var svg = new SVG();
svg.init();
svg.setScale(this.scale);
svg.setTab(true);
svg.setInnies([true]);
svg.setSlot(true);
if (this.fontsize) {
svg.setFontSize(this.fontsize);
}
svg.setExpand(30 + this.extraWidth, 0, 0, 0);
var artwork = svg.basicBlock();
return [artwork, svg.docks];
};
// E.g., wait for
this.oneBooleanArgBlock = function () {
this.args = 1;
this.size = 2.6;
this.dockTypes.push('out');
this.dockTypes.push('booleanin');
this.dockTypes.push('in');
this.generator = this.oneBooleanArgBlockGenerator;
};
this.oneBooleanArgBlockGenerator = function () {
var svg = new SVG();
svg.init();
svg.setScale(this.scale);
svg.setTab(true);
svg.setSlot(true);
svg.setBoolean(true);
svg.setClampCount(0);
if (this.fontsize) {
svg.setFontSize(this.fontsize);
}
svg.setExpand(30 + this.extraWidth, 0, 0, 0);
var artwork = svg.basicClamp();
return [artwork, svg.docks];
};
// E.g., setxy. These are expandable.
this.twoArgBlock = function () {
this.expandable = true;
this.style = 'twoarg';
this.size = 2;
this.args = 2;
this.dockTypes.push('out');
this.dockTypes.push('numberin');
this.dockTypes.push('numberin');
this.dockTypes.push('in');
this.generator = this.twoArgBlockGenerator;
};
this.twoArgBlockGenerator = function (expandY) {
var svg = new SVG();
svg.init();
svg.setScale(this.scale);
svg.setTab(true);
svg.setInnies([true, true]);
svg.setSlot(true);
if (expandY) {
svg.setExpand(30 + this.extraWidth, (expandY - 1) * STANDARDBLOCKHEIGHT / 2, 0, 0);
} else {
svg.setExpand(30 + this.extraWidth, 0, 0, 0);
}
if (this.fontsize) {
svg.setFontSize(this.fontsize);
}
var artwork = svg.basicBlock();
return [artwork, svg.docks];
};
// E.g., ??? These are expandable.
this.threeArgBlock = function () {
this.expandable = true;
this.style = 'twoarg';
this.size = 3;
this.args = 3;
this.dockTypes.push('out');
this.dockTypes.push('numberin');
this.dockTypes.push('numberin');
this.dockTypes.push('numberin');
this.dockTypes.push('in');
this.generator = this.threeArgBlockGenerator;
};
this.threeArgBlockGenerator = function (expandY) {
var svg = new SVG();
svg.init();
svg.setScale(this.scale);
svg.setTab(true);
svg.setInnies([true, true, true]);
svg.setSlot(true);
if (expandY) {
svg.setExpand(30 + this.extraWidth, (expandY - 1) * STANDARDBLOCKHEIGHT / 2, 0, 0);
} else {
svg.setExpand(30 + this.extraWidth, 0, 0, 0);
}
if (this.fontsize) {
svg.setFontSize(this.fontsize);
}
var artwork = svg.basicBlock();
return [artwork, svg.docks];
};
// E.g., sqrt, box
this.oneArgMathBlock = function () {
this.style = 'arg';
this.size = 1;
this.args = 1;
this.parameter = true;
this.dockTypes.push('numberout');
this.dockTypes.push('numberin');
this.generator = this.oneArgMathBlockGenerator;
};
this.oneArgMathBlockGenerator = function () {
var svg = new SVG();
svg.init();
svg.setScale(this.scale);
svg.setSlot(false);
svg.setInnies([true]);
svg.setOutie(true);
svg.setTab(false);
if (this.fontsize) {
svg.setFontSize(this.fontsize);
}
svg.setExpand(30 + this.extraWidth, 0, 0, 0);
var artwork = svg.basicBlock();
return [artwork, svg.docks];
};
// E.g., plus, minus, multiply, divide, power. These are also expandable.
this.twoArgMathBlock = function () {
this.expandable = true;
this.style = 'arg';
this.size = 2;
this.args = 2;
this.parameter = true;
this.dockTypes.push('numberout');
this.dockTypes.push('numberin');
this.dockTypes.push('numberin');
this.generator = this.twoArgMathBlockGenerator;
};
this.twoArgMathBlockGenerator = function (expandY) {
var svg = new SVG();
svg.init();
svg.setScale(this.scale);
svg.setSlot(false);
svg.setInnies([true, true]);
svg.setOutie(true);
svg.setTab(false);
if (expandY) {
svg.setExpand(30 + this.extraWidth, (expandY - 1) * STANDARDBLOCKHEIGHT / 2, 0, 0);
} else {
svg.setExpand(30 + this.extraWidth, 0, 0, 0);
}
if (this.fontsize) {
svg.setFontSize(this.fontsize);
}
var artwork = svg.basicBlock();
return [artwork, svg.docks];
};
//
this.threeArgMathBlock = function () {
this.expandable = true;
this.style = 'arg';
this.size = 3;
this.args = 3;
this.parameter = true;
this.dockTypes.push('numberout');
this.dockTypes.push('numberin');
this.dockTypes.push('numberin');
this.dockTypes.push('numberin');
this.generator = this.threeArgMathBlockGenerator;
};
this.threeArgMathBlockGenerator = function (expandY) {
var svg = new SVG();
svg.init();
svg.setScale(this.scale);
svg.setSlot(false);
svg.setInnies([true, true, true]);
svg.setOutie(true);
svg.setTab(false);
if (expandY) {
svg.setExpand(30 + this.extraWidth, (expandY - 1) * STANDARDBLOCKHEIGHT / 2, 0, 0);
} else {
svg.setExpand(30 + this.extraWidth, 0, 0, 0);
}
if (this.fontsize) {
svg.setFontSize(this.fontsize);
}
var artwork = svg.basicBlock();
return [artwork, svg.docks];
};
// E.g., number, string. Value blocks get DOM textareas associated
// with them so their values can be edited by the user.
this.valueBlock = function () {
this.style = 'value';
this.size = 1;
this.args = 0;
this.dockTypes.push('numberout');
this.generator = this.valueBlockGenerator;
};
this.valueBlockGenerator = function () {
var svg = new SVG();
svg.init();
svg.setScale(this.scale);
// Extra room for parameter label
svg.setExpand(60 + this.extraWidth, 0, 0, 0);
svg.setOutie(true);
if (this.fontsize) {
svg.setFontSize(this.fontsize);
}
var artwork = svg.basicBox();
return [artwork, svg.docks];
};
// E.g., media. Media blocks invoke a chooser and a thumbnail
// image is overlayed to represent the data associated with the
// block.
this.mediaBlock = function () {
this.style = 'value';
this.size = 2;
this.args = 0;
this.dockTypes.push('mediaout');
this.generator = this.mediaBlockGenerator;
};
this.mediaBlockGenerator = function () {
var svg = new SVG();
svg.init();
svg.setScale(this.scale);
// Extra room for graphics
svg.setExpand(60 + this.extraWidth, 23, 0, 0);
svg.setOutie(true);
if (this.fontsize) {
svg.setFontSize(this.fontsize);
}
var artwork = svg.basicBox();
return [artwork, svg.docks];
};
// E.g., start. A "child" flow is docked in an expandable clamp.
// There are no additional arguments and no flow above or below.
this.stackClampZeroArgBlock = function () {
this.style = 'clamp';
this.expandable = true;
this.size = 3;
this.args = 1;
this.dockTypes.push('unavailable');
this.dockTypes.push('in');
this.dockTypes.push('unavailable');
this.generator = this.stackClampZeroArgBlockGenerator;
};
this.stackClampZeroArgBlockGenerator = function (slots) {
var svg = new SVG();
svg.init();
svg.setScale(this.scale);
svg.setCap(true);
svg.setTail(true);
svg.setExpand(20 + this.extraWidth, 0, 0, 0);
if (slots) {
svg.setClampSlots(0, slots);
} else {
svg.setClampSlots(0, 1);
}
if (this.fontsize) {
svg.setFontSize(this.fontsize);
}
var artwork = svg.basicClamp();
return [artwork, svg.docks];
};
// E.g., emptyclamp. Unlike start, there is a flow above and below.
this.flowClampBlock = function () {
this.style = 'clamp';
this.expandable = true;
this.size = 2;
this.args = 1;
this.dockTypes.push('out');
this.dockTypes.push('in');
this.dockTypes.push('in');
this.generator = this.flowClampBlockGenerator;
};
this.flowClampBlockGenerator = function (slots) {
var svg = new SVG();
svg.init();
svg.setScale(this.scale);
svg.setTab(true);
svg.setSlot(true);
svg.setExpand(20 + this.extraWidth, 0, 0, 0);
if (slots) {
svg.setClampSlots(0, slots);
} else {
svg.setClampSlots(0, 1);
}
if (this.fontsize) {
svg.setFontSize(this.fontsize);
}
var artwork = svg.basicClamp();
return [artwork, svg.docks];
};
// E.g., repeat. Unlike action, there is a flow above and below.
this.flowClampOneArgBlock = function () {
this.style = 'clamp';
this.expandable = true;
this.size = 2;
this.args = 2;
this.dockTypes.push('out');
this.dockTypes.push('numberin');
this.dockTypes.push('in');
this.dockTypes.push('in');
this.generator = this.flowClampOneArgBlockGenerator;
};
this.flowClampOneArgBlockGenerator = function (slots) {
var svg = new SVG();
svg.init();
svg.setScale(this.scale);
svg.setTab(true);
svg.setSlot(true);
svg.setInnies([true]);
svg.setExpand(20 + this.extraWidth, 0, 0, 0);
if (slots) {
svg.setClampSlots(0, slots);
} else {
svg.setClampSlots(0, 1);
}
if (this.fontsize) {
svg.setFontSize(this.fontsize);
}
var artwork = svg.basicClamp();
return [artwork, svg.docks];
};
// E.g., tuplet, which takes two args plus an interior flow. There is a flow above and below.
this.flowClampTwoArgBlock = function () {
this.style = 'clamp';
this.expandable = true;
this.size = 3;
this.args = 3;
this.dockTypes.push('out');
this.dockTypes.push('numberin');
this.dockTypes.push('numberin');
this.dockTypes.push('in');
this.dockTypes.push('in');
this.generator = this.flowClampTwoArgBlockGenerator;
};
this.flowClampTwoArgBlockGenerator = function (slots) {
var svg = new SVG();
svg.init();
svg.setScale(this.scale);
svg.setTab(true);
svg.setSlot(true);
svg.setInnies([true, true]);
svg.setExpand(20 + this.extraWidth, 0, 0, 0);
if (slots) {
svg.setClampSlots(0, slots);
} else {
svg.setClampSlots(0, 1);
}
if (this.fontsize) {
svg.setFontSize(this.fontsize);
}
var artwork = svg.basicClamp();
return [artwork, svg.docks];
};
this.flowClampThreeArgBlock = function (){
this.style = 'clamp';
this.expandable = true;
this.size = 4;
this.args = 4;
this.dockTypes.push('out');
this.dockTypes.push('numberin');
this.dockTypes.push('numberin');
this.dockTypes.push('textin');
this.dockTypes.push('in');
this.dockTypes.push('in');
this.generator = this.flowClampThreeArgBlockGenerator;
};
this.flowClampThreeArgBlockGenerator = function (slots) {
var svg = new SVG();
svg.init();
svg.setScale(this.scale);
svg.setTab(true);
svg.setSlot(true);
svg.setInnies([true, true,true]);
svg.setExpand(20 + this.extraWidth, 0, 0, 0);
if (slots) {
svg.setClampSlots(0, slots);
} else {
svg.setClampSlots(0, 1);
}
if (this.fontsize) {
svg.setFontSize(this.fontsize);
}
var artwork = svg.basicClamp();
return [artwork, svg.docks];
};
// E.g., do with args: innies instead of interior slots.
this.argClampOneArgBlock = function () {
this.style = 'argclamp';
this.expandable = true;
this.size = 3;
this.args = 2;
this.dockTypes.push('out');
this.dockTypes.push('textin');
this.dockTypes.push('anyin');
this.dockTypes.push('in');
this.generator = this.argClampOneArgBlockGenerator;
};
this.argClampOneArgBlockGenerator = function (slots) {
var svg = new SVG();
svg.init();
svg.setScale(this.scale);
svg.setTab(true);
svg.setSlot(true);
svg.setInnies([true]);
svg.setExpand(20 + this.extraWidth, 0, 0, 0);
if (slots) {
svg.setClampSlots(0, slots);
} else {
svg.setClampSlots(0, [1]);
}
if (this.fontsize) {
svg.setFontSize(this.fontsize);
}
var artwork = svg.argClamp();
return [artwork, svg.docks];
};
// E.g., calculate with args: innies instead of interior slots.
this.argClampOneArgMathBlock = function () {
this.style = 'argclamparg';
this.expandable = true;
this.size = 3;
this.args = 2;
this.dockTypes.push('anyout');
this.dockTypes.push('textin');
this.dockTypes.push('anyin');
this.generator = this.argClampOneArgMathBlockGenerator;
};
this.argClampOneArgMathBlockGenerator = function (slots) {
var svg = new SVG();
svg.init();
svg.setScale(this.scale);
svg.setInnies([true]);
svg.setOutie(true);
svg.setTab(false);
svg.setSlot(false);
svg.setExpand(20 + this.extraWidth, 0, 0, 0);
if (slots) {
svg.setClampSlots(0, slots);
} else {
svg.setClampSlots(0, [1]);
}
if (this.fontsize) {
svg.setFontSize(this.fontsize);
}
var artwork = svg.argClamp();
return [artwork, svg.docks];
};
// E.g., named do with args: innies instead of interior slots.
this.argClampBlock = function () {
this.style = 'argclamp';
this.expandable = true;
this.size = 3;
this.args = 1;
this.dockTypes.push('out');
this.dockTypes.push('anyin');
this.dockTypes.push('in');
this.generator = this.argClampBlockGenerator;
};
this.argClampBlockGenerator = function (slots) {
var svg = new SVG();
svg.init();
svg.setScale(this.scale);
svg.setTab(true);
svg.setSlot(true);
svg.setExpand(20 + this.extraWidth, 0, 0, 0);
if (slots) {
svg.setClampSlots(0, slots);
} else {
svg.setClampSlots(0, [1]);
}
if (this.fontsize) {
svg.setFontSize(this.fontsize);
}
var artwork = svg.argClamp();
return [artwork, svg.docks];
};
// E.g., named calculate with args: innies instead of interior slots.
this.argClampMathBlock = function () {
this.style = 'argclamparg';
this.expandable = true;
this.size = 3;
this.args = 1;
this.dockTypes.push('anyout');
this.dockTypes.push('anyin');
this.generator = this.argClampMathBlockGenerator;
};
this.argClampMathBlockGenerator = function (slots) {
var svg = new SVG();
svg.init();
svg.setScale(this.scale);
svg.setOutie(true);
svg.setTab(false);
svg.setSlot(false);
svg.setExpand(20 + this.extraWidth, 0, 0, 0);
if (slots) {
svg.setClampSlots(0, slots);
} else {
svg.setClampSlots(0, [1]);
}
if (this.fontsize) {
svg.setFontSize(this.fontsize);
}
var artwork = svg.argClamp();
return [artwork, svg.docks];
};
// E.g., if. A "child" flow is docked in an expandable clamp. The
// additional argument is a boolean. There is flow above and below.
this.flowClampBooleanArgBlock = function () {
this.style = 'clamp';
this.expandable = true;
this.size = 3;
this.args = 2;
this.dockTypes.push('out');
this.dockTypes.push('booleanin');
this.dockTypes.push('in');
this.dockTypes.push('in');
this.generator = this.flowClampBooleanArgBlockGenerator;
};
this.flowClampBooleanArgBlockGenerator = function (slots) {
var svg = new SVG();
svg.init();
svg.setScale(this.scale);
svg.setTab(true);
svg.setBoolean(true);
svg.setSlot(true);
svg.setExpand(this.extraWidth, 0, 0, 0);
if (slots) {
svg.setClampSlots(0, slots);
} else {
svg.setClampSlots(0, 1);
}
if (this.fontsize) {
svg.setFontSize(this.fontsize);
}
var artwork = svg.basicClamp();
return [artwork, svg.docks];
};
// E.g., if then else. Two "child" flows are docked in expandable
// clamps. The additional argument is a boolean. There is flow
// above and below.
this.doubleFlowClampBooleanArgBlock = function () {
this.style = 'doubleclamp';
this.expandable = true;
this.size = 4;
this.args = 3;
this.dockTypes.push('out');
this.dockTypes.push('booleanin');
this.dockTypes.push('in');
this.dockTypes.push('in');
this.dockTypes.push('in');
this.generator = this.doubleFlowClampBooleanArgBlockGenerator;
};
this.doubleFlowClampBooleanArgBlockGenerator = function (bottomSlots, topSlots) {
var svg = new SVG();
svg.init();
svg.setScale(this.scale);
svg.setTab(true);
svg.setSlot(true);
svg.setBoolean(true);
svg.setClampCount(2);
if (topSlots) {
svg.setClampSlots(0, topSlots);
} else {
svg.setClampSlots(0, 1);
}
if (bottomSlots) {
svg.setClampSlots(1, bottomSlots);
} else {
svg.setClampSlots(1, 1);
}
svg.setExpand(this.extraWidth, 0, 0, 0);
if (this.fontsize) {
svg.setFontSize(this.fontsize);
}
var artwork = svg.basicClamp();
return [artwork, svg.docks];
};
// E.g., forever. Unlike start, there is flow above and below.
this.flowClampZeroArgBlock = function () {
this.style = 'clamp';
this.expandable = true;
this.size = 2;
this.args = 1;
this.dockTypes.push('out');
this.dockTypes.push('in');
this.dockTypes.push('in');
this.generator = this.flowClampZeroArgBlockGenerator;
};
this.flowClampZeroArgBlockGenerator = function (slots) {
var svg = new SVG();
svg.init();
svg.setScale(this.scale);
svg.setTab(true);
svg.setSlot(true);
svg.setExpand(10 + this.extraWidth, 0, 0, 0);
if (slots) {
svg.setClampSlots(0, slots);
} else {
svg.setClampSlots(0, 1);
}
if (this.fontsize) {
svg.setFontSize(this.fontsize);
}
var artwork = svg.basicClamp();
return [artwork, svg.docks];
};
// E.g., count clamp: math block with interior slots
this.argFlowClampBlock = function () {
this.style = 'argflowclamp';
this.expandable = true;
this.size = 3;
this.args = 2;
this.dockTypes.push('anyout');
this.dockTypes.push('in');
this.generator = this.argFlowClampGenerator;
};
this.argFlowClampGenerator = function (slots) {
var svg = new SVG();
svg.init();
svg.setScale(this.scale);
svg.setSlot(false);
svg.setOutie(true);
svg.setExpand(20 + this.extraWidth, 0, 0, 0);
if (slots) {
svg.setClampSlots(0, slots);
} else {
svg.setClampSlots(0, [1]);
}
if (this.fontsize) {
svg.setFontSize(this.fontsize);
}
var artwork = svg.basicClamp();
return [artwork, svg.docks];
};
// E.g., action. A "child" flow is docked in an expandable clamp.
// The additional argument is a name. Again, no flow above or below.
this.stackClampOneArgBlock = function () {
this.style = 'clamp';
this.expandable = true;
this.size = 3;
this.args = 2;
this.dockTypes.push('unavailable');
this.dockTypes.push('anyin');
this.dockTypes.push('in');
this.dockTypes.push('unavailable');
this.generator = this.stackClampOneArgBlockGenerator;
};
this.stackClampOneArgBlockGenerator = function (slots) {
var svg = new SVG();
svg.init();
svg.setScale(this.scale);
svg.setCap(true);
svg.setTail(true);
svg.setInnies([true]);
svg.setExpand(10 + this.extraWidth, 0, 0, 0);
if (slots) {
svg.setClampSlots(0, slots);
} else {
svg.setClampSlots(0, 1);
}
if (this.fontsize) {
svg.setFontSize(this.fontsize);
}
var artwork = svg.basicClamp();
return [artwork, svg.docks];
};
// E.g., mouse button.
this.booleanZeroArgBlock = function () {
this.style = 'arg';
this.size = 1;
this.args = 0;
this.dockTypes.push('booleanout');
this.generator = this.booleanZeroArgBlockGenerator;
};
this.booleanZeroArgBlockGenerator = function () {
var svg = new SVG();
svg.init();
svg.setScale(this.scale);
svg.setExpand(60 + this.extraWidth, 0, 0, 4);
if (this.fontsize) {
svg.setFontSize(this.fontsize);
}
var artwork = svg.booleanNot(true);
return [artwork, svg.docks];
};
// E.g., named sensor blocks
this.booleanOneArgBlock = function () {
this.style = 'arg';
this.size = 2;
this.args = 1;
this.parameter = true;
this.dockTypes.push('booleanout');
this.dockTypes.push('textin');
this.generator = this.booleanOneArgBlockGenerator;
};
this.booleanOneArgBlockGenerator = function () {
var svg = new SVG();
svg.init();
svg.setScale(this.scale);
svg.setExpand(20 + this.extraWidth, 0, 0, 0);
if (this.fontsize) {
svg.setFontSize(this.fontsize);
}
svg.setInnies([true]);
var artwork = svg.booleanNot(true); // OneArg
return [artwork, svg.docks];
};
// E.g., not
this.booleanOneBooleanArgBlock = function () {
this.style = 'arg';
this.size = 2;
this.args = 1;
this.parameter = true;
this.dockTypes.push('booleanout');
this.dockTypes.push('booleanin');
this.generator = this.booleanOneBooleanArgBlockGenerator;
};
this.booleanOneBooleanArgBlockGenerator = function () {
var svg = new SVG();
svg.init();
svg.setScale(this.scale);
svg.setExpand(20 + this.extraWidth, 0, 0, 0);
if (this.fontsize) {
svg.setFontSize(this.fontsize);
}
var artwork = svg.booleanNot(false);
return [artwork, svg.docks];
};
// E.g., and, or
this.booleanTwoBooleanArgBlock = function () {
this.style = 'arg';
this.size = 3;
this.args = 2;
this.parameter = true;
this.dockTypes.push('booleanout');
this.dockTypes.push('booleanin');
this.dockTypes.push('booleanin');
this.generator = this.booleanTwoBooleanArgBlockGenerator;
};
this.booleanTwoBooleanArgBlockGenerator = function () {
var svg = new SVG();
svg.init();
svg.setScale(this.scale);
svg.setExpand(20 + this.extraWidth, 0, 0, 0);
if (this.fontsize) {
svg.setFontSize(this.fontsize);
}
var artwork = svg.booleanAndOr();
return [artwork, svg.docks];
};
// E.g., greater, less, equal
this.booleanTwoArgBlock = function () {
this.style = 'arg';
this.size = 2;
this.args = 2;
this.parameter = true;
this.expandable = true;
this.dockTypes.push('booleanout');
this.dockTypes.push('numberin');
this.dockTypes.push('numberin');
this.generator = this.booleanTwoArgBlockGenerator;
};
this.booleanTwoArgBlockGenerator = function (expandY) {
var svg = new SVG();
svg.init();
svg.setScale(this.scale);
if (expandY) {
svg.setExpand(10 + this.extraWidth, (expandY - 1) * STANDARDBLOCKHEIGHT / 2, 0, 0);
} else {
svg.setExpand(10 + this.extraWidth, 0, 0, 0);
}
if (this.fontsize) {
svg.setFontSize(this.fontsize);
}
var artwork = svg.booleanCompare();
return [artwork, svg.docks];
};
// E.g., color, shade, pensize, ...
this.parameterBlock = function () {
this.style = 'arg';
this.parameter = true;
this.size = 1;
this.args = 0;
this.dockTypes.push('numberout');
this.generator = this.parameterBlockGenerator;
};
this.parameterBlockGenerator = function () {
var svg = new SVG();
svg.init();
svg.setScale(this.scale);
// Extra room for parameter label
svg.setExpand(70 + this.extraWidth, 0, 0, 0);
svg.setOutie(true);
if (this.fontsize) {
svg.setFontSize(this.fontsize);
}
var artwork = svg.basicBox();
return [artwork, svg.docks];
};
};