Commit f3430016 authored by neil.fraser@gmail.com's avatar neil.fraser@gmail.com

Initial upload.

git-svn-id: http://blockly.googlecode.com/svn/trunk@2 c400ca83-b69d-9dd7-9705-49c6b8615e23
parent dbd62991
1x1.gif

43 Bytes

This diff is collapsed.
This diff is collapsed.
<html>
<head>
<title>Block Factory</title>
<script type="text/javascript" src="blockly.js"></script>
<script type="text/javascript" src="block.js"></script>
<script type="text/javascript" src="blockSvg.js"></script>
<script type="text/javascript" src="comment.js"></script>
<script type="text/javascript" src="connection.js"></script>
<script type="text/javascript" src="contextmenu.js"></script>
<script type="text/javascript" src="field.js"></script>
<script type="text/javascript" src="field_dropdown.js"></script>
<script type="text/javascript" src="field_label.js"></script>
<script type="text/javascript" src="field_textinput.js"></script>
<script type="text/javascript" src="generator.js"></script>
<script type="text/javascript" src="inject.js"></script>
<script type="text/javascript" src="language_core.js"></script>
<script type="text/javascript" src="language_docs.js"></script>
<script type="text/javascript" src="javascript_core.js"></script>
<script type="text/javascript" src="javascript_docs.js"></script>
<script type="text/javascript" src="mutator.js"></script>
<script type="text/javascript" src="scrollbar.js"></script>
<script type="text/javascript" src="toolbox.js"></script>
<script type="text/javascript" src="tooltip.js"></script>
<script type="text/javascript" src="trashcan.js"></script>
<script type="text/javascript" src="variables.js"></script>
<script type="text/javascript" src="workspace.js"></script>
<script type="text/javascript" src="xml.js"></script>
<script type="text/javascript">
// Depending on the URL argument, render as LTR or RTL.
var rtl = (document.location.search == '?rtl');
var block = null;
function start() {
Blockly.inject(document.getElementById('svg'), {'rtl': rtl});
// Populate the colour dropdown with all available colours.
var select = document.getElementById('colour');
for (var colour in Blockly.COLOURS) {
select.appendChild(new Option(colour));
}
}
function createCustomBlock() {
block = new Blockly.Block(Blockly.mainWorkspace, '');
block.svg_.svgGroup_.setAttribute('transform', 'translate(60, 40)');
block.render();
document.getElementById('blockFactoryForm').reset();
document.getElementById('customTbody').style.display = 'table-row-group';
}
function setColour() {
block.setColour(document.getElementById('colour').value);
}
function addTitle() {
var type = document.getElementById('titleType').value;
var title = document.getElementById('titleLabel').value;
if (type == 'textInput') {
title = new Blockly.FieldTextInput(title);
}
var index = parseInt(document.getElementById('titleIndex').value, 10);
if (isNaN(index)) {
block.addTitle(title);
} else {
block.addTitle(title, index);
}
}
function setTooltip() {
block.setTooltip(document.getElementById('tooltip').value);
}
function setPreviousStatement() {
try {
block.setPreviousStatement(
document.getElementById('previousStatement').checked);
} finally {
document.getElementById('previousStatement').checked =
!!block.previousConnection;
}
}
function setNextStatement() {
try {
block.setNextStatement(document.getElementById('nextStatement').checked);
} finally {
document.getElementById('nextStatement').checked = !!block.nextConnection;
}
}
function setOutput() {
try {
block.setOutput(document.getElementById('output').checked);
} finally {
document.getElementById('output').checked = !!block.outputConnection;
}
}
function setCollapsed() {
block.setCollapsed(document.getElementById('collapsed').checked);
}
function setInputsInline() {
block.setInputsInline(document.getElementById('inputsInline').checked);
}
function addInput() {
var type = parseInt(document.getElementById('inputType').value, 10);
var label = document.getElementById('inputLabel').value;
var tooltip = document.getElementById('inputTooltip').value;
var index = parseInt(document.getElementById('inputIndex').value, 10);
if (isNaN(index)) {
block.addInput(label, tooltip, type);
} else {
block.addInput(label, tooltip, type, index);
}
}
function removeInput() {
var index = parseInt(document.getElementById('removeInputIndex').value, 10);
block.removeInput(index);
}
function toJavaScript() {
var output = document.getElementById('importExport');
output.value = Blockly.Generator.workspaceToCode('JavaScript');
}
function toXml() {
var output = document.getElementById('importExport');
var xml = Blockly.Xml.workspaceToDom(Blockly.mainWorkspace);
output.value = Blockly.Xml.domToText(xml);
}
function fromXml() {
var input = document.getElementById('importExport');
var xml = Blockly.Xml.textToDom(input.value);
Blockly.Xml.domToWorkspace(Blockly.mainWorkspace, xml);
}
function airstrike(n) {
var prototypes = [];
for (var prototype in Blockly.Language) {
if (prototype != '$') {
prototypes.push(prototype);
}
}
for (var x = 0; x < n; x++) {
var prototype = prototypes[Math.floor(Math.random() * prototypes.length)];
var block = new Blockly.Block(Blockly.mainWorkspace, prototype);
block.svg_.svgGroup_.setAttribute('transform', 'translate(' +
Math.round(Math.random() * 450 + 40) + ', ' +
Math.round(Math.random() * 600 + 40) + ')');
block.render();
}
}
</script>
<style>
body {
background-color: white;
font-family: sans-serif;
}
h1 {
font-weight: normal;
font-size: 140%;
}
#svg {
float: right;
height: 95%;
width: 70%;
}
</style>
</head>
<body onload="start()">
<div id="svg"></div>
<h1>Block Factory</h1>
<p><a href="javascript:void(document.getElementById('svg').style.display = 'block')">Show</a> - <a href="javascript:void(document.getElementById('svg').style.display = 'none')">Hide</a></p>
<script type="text/javascript">
if (rtl) {
document.write('[ &larr; RTL. Switch to <A HREF="?ltr">LTR</A>. ]');
} else {
document.write('[ &rarr; LTR. Switch to <A HREF="?rtl">RTL</A>. ]');
}
</script>
<p>
<input type="button" value="Generate JavaScript" onclick="toJavaScript()">
&nbsp;
<input type="button" value="Export to XML" onclick="toXml()">
&nbsp;
<input type="button" value="Import from XML" onclick="fromXml()">
<br>
<textarea id="importExport" style="width: 26%; height: 12em"></textarea>
</p>
<hr>
<form id="blockFactoryForm" onsubmit="return false;">
<table>
<thead>
<tr>
<td colspan=2>Stress the renderer with a
<input type="button" onclick="createCustomBlock()" value="Custom Block">
</td>
</tr>
</thead>
<tbody id="customTbody" style="display: none">
<tr>
<td>Colour:</td>
<td>
<select id="colour" onchange="setColour()">
<option>--</option>
</select>
</td>
</tr>
<tr>
<td>New title:</td>
<td><select id="titleType"><option value="label">Label</option><option value="textInput">Text Input</option></select> with text <input type="text" id="titleLabel"> at <input id="titleIndex" type="number" min="0" style="width: 3em">
<input type="button" onclick="addTitle()" value="Add"></td>
</tr>
<tr>
<td>Tooltip:</td>
<td><textarea id="tooltip" onchange="setTooltip()" onkeyup="setTooltip()"></textarea>
</tr>
<tr>
<td>Previous statement:</td>
<td><input type="checkbox" id="previousStatement" onchange="setPreviousStatement()"></td>
</tr>
<tr>
<td>Next statement:</td>
<td><input type="checkbox" id="nextStatement" onchange="setNextStatement()"></td>
</tr>
<tr>
<td>Output:</td>
<td><input type="checkbox" id="output" onchange="setOutput()"></td>
</tr>
<tr>
<td>Collapsed:</td>
<td><input type="checkbox" id="collapsed" onchange="setCollapsed()"></td>
</tr>
<tr>
<td>Inline inputs:</td>
<td><input type="checkbox" id="inputsInline" onchange="setInputsInline()"></td>
</tr>
<tr>
<td>New input:</td>
<td><select id="inputType"><option value=1>Value</option><option value=3>Statement</option><option value=5>Variable</option></select> called <input type="text" id="inputLabel"> at <input id="inputIndex" type="number" min="0" style="width: 3em"><br>
with tooltip <input id="inputTooltip" type="text"> <input type="button" onclick="addInput()" value="Add"></td>
</tr>
<tr>
<td>Remove input:</td>
<td>At <input id="removeInputIndex" type="number" min="0" style="width: 3em">
<input type="button" onclick="removeInput()" value="Remove"></td>
</tr>
</tbody>
</table>
<hr>
<p>
Stress test with an <input type="button" value="Airstrike!" onclick="airstrike(100)">
</p>
</form>
</body>
</html>
This diff is collapsed.
/**
* Visual Blocks Editor
*
* Copyright 2012 Google Inc.
* http://code.google.com/p/google-blockly/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Style sheet for a Blockly editor.
* @author fraser@google.com (Neil Fraser)
*/
.blocklySvg {
border: 1px solid black;
}
.blocklyDraggable {
/* Hotspot coordinates are baked into the CUR file, but they are still
required in the CSS due to a Chrome bug.
http://code.google.com/p/chromium/issues/detail?id=1446 */
cursor: url(media/handopen.cur) 8 5, auto;
}
.blocklyResizeSE {
fill: #aaa;
cursor: se-resize;
}
.blocklyResizeSW {
fill: #aaa;
cursor: sw-resize;
}
.blocklyResizeLine {
stroke-width: 1;
stroke: #888;
}
.blocklyHighlightedConnectionPath {
stroke-width: 4px;
stroke: #fc3;
fill: none;
}
.blocklySelected {
stroke-width: 3px;
stroke: #fc3;
}
.blocklyDragging {
fill-opacity: 0.8;
stroke-opacity: 0.8;
}
.blocklyText {
cursor: default;
font-family: sans-serif;
font-size: 11pt;
fill: #fff;
}
.blocklyHeader {
cursor: default !important;
font-family: sans-serif;
font-size: 15pt;
fill: #000;
}
.blocklyNonEditableText>rect {
fill: #fff;
fill-opacity: 0.2;
}
.blocklyEditableText>rect {
fill: #fff;
fill-opacity: 0.2;
}
.blocklyEditableText:hover>rect {
stroke-width: 1;
stroke: #fff;
}
.blocklyEditableHighlight {
stroke-linecap: round;
stroke-width: 1;
stroke: #fff;
stroke-opacity: 0.5;
fill: none;
}
/*
* Don't allow users to select text.
* It gets annoying when trying to drag a block and selected text moves instead.
*/
.blocklySvg text {
-moz-user-select: none;
-webkit-user-select: none;
user-select: none;
cursor: inherit;
}
.blocklyHidden {
display: none;
}
.blocklyTooltipBackground {
fill: #ffffc7;
stroke-width: 1px;
stroke: #d8d8d8;
}
.blocklyTooltipShadow,
.blocklyContextMenuShadow,
.blocklyDropdownMenuShadow {
fill: #bbb;
filter: url(#blocklyShadowFilter);
}
.blocklyTooltipText {
font-family: sans-serif;
font-size: 9pt;
fill: #000;
}
.blocklyIconShield {
cursor: default;
fill: #00c;
stroke-width: 1px;
stroke: #ccc;
}
.blocklyMutatorMark {
cursor: default;
fill: #ccc;
}
.blocklyIconGroup:hover>.blocklyIconShield {
fill: #00f;
stroke: #fff;
}
.blocklyIconGroup:hover>.blocklyMutatorMark {
fill: #fff;
}
.blocklyCommentMark {
cursor: default !important;
font-family: sans-serif;
font-size: 9pt;
font-weight: bold;
fill: #ccc;
}
.blocklyMinimalBody {
margin: 0;
padding: 0;
}
.blocklyCommentTextarea {
margin: 0;
padding: 2px;
border: 0;
resize: none;
background-color: #ffc;
}
.blocklyHtmlInput {
font-family: sans-serif;
font-size: 11pt;
}
.blocklyContextMenuBackground,
.blocklyMutatorBackground {
fill: #fff;
stroke-width: 1;
stroke: #ddd;
}
.blocklyContextMenuOptions>.blocklyMenuDiv,
.blocklyContextMenuOptions>.blocklyMenuDivDisabled,
.blocklyDropdownMenuOptions>.blocklyMenuDiv {
fill: #fff;
}
.blocklyToolboxOptions>.blocklyMenuDiv {
fill: #ddd;
}
.blocklyToolboxOptions>.blocklyMenuDiv:hover {
fill: #e4e4e4;
}
.blocklyContextMenuOptions>.blocklyMenuDiv:hover>rect,
.blocklyDropdownMenuOptions>.blocklyMenuDiv:hover>rect {
fill: #57e;
}
.blocklyMenuSelected>rect {
fill: #57e;
}
.blocklyMenuText {
cursor: default !important;
font-family: sans-serif;
font-size: 15px; /* All context menu sizes are based on pixels. */
fill: #000;
}
.blocklyContextMenuOptions>.blocklyMenuDiv:hover>.blocklyMenuText,
.blocklydropdownMenuOptions>.blocklyMenuDiv:hover>.blocklyMenuText {
fill: #fff;
}
.blocklyMenuSelected>.blocklyMenuText {
fill: #fff;
}
.blocklyMenuDivDisabled>.blocklyMenuText {
fill: #ccc;
}
.blocklyToolboxBackground {
fill: #ddd;
}
.blocklyFlyoutBackground {
fill: #ddd;
fill-opacity: 0.8;
}
.blocklyScrollbarBackground {
fill: #fff;
stroke-width: 1;
stroke: #e4e4e4;
}
.blocklyScrollbarKnob {
fill: #ccc;
}
.blocklyScrollbarBackground:hover+.blocklyScrollbarKnob,
.blocklyScrollbarKnob:hover {
fill: #bbb;
}
.blocklyInvalidInput {
background: #faa;
}
.blocklyScreenShadow {
fill: #000;
fill-opacity: 0.3;
}
.blocklyButtonBackground {
fill: #eee;
stroke: #ddd;
stroke-width: 1;
}
.blocklyButton:active>.blocklyButtonBackground {
stroke: #00f;
stroke-width: 1;
}
.blocklyButtonText {
cursor: default !important;
font-family: sans-serif;
font-size: 13pt;
fill: #000;
}
.blocklyLaunchButton>.blocklyButtonBackground {
fill: #f00;
}
.blocklyLaunchButton>.blocklyButtonText {
fill: #fff;
}
.blocklyButtonShadow {
fill: #bbb;
filter: url(#blocklyShadowFilter);
display: none;
}
.blocklyLaunchButton>.blocklyButtonShadow {
fill: #999;
}
.blocklyButton:hover>.blocklyButtonShadow {
display: block;
}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/**
* Visual Blocks Editor
*
* Copyright 2012 Google Inc.
* http://code.google.com/p/google-blockly/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Input field. Used for editable titles, variables, etc.
* This is an abstract class that defines the UI on the block. Actual
* instances would be Blockly.FieldTextInput, Blockly.FieldDropdown, etc.
* @author fraser@google.com (Neil Fraser)
*/
/**
* Class for an editable field.
* @param {?string} text The initial content of the field.
* @constructor
*/
Blockly.Field = function(text) {
if (text === null) {
// This is a Field instance to be used in inheritance.
return;
}
this.sourceBlock_ = null;
// Build the DOM.
this.group_ = Blockly.createSvgElement('g', {}, null);
this.textElement_ = Blockly.createSvgElement('text',
{class: 'blocklyText'}, this.group_);
this.borderRect_ = Blockly.createSvgElement('rect', {}, this.group_);
this.highlight_ = Blockly.createSvgElement('path',
{class: 'blocklyEditableHighlight'}, this.group_);
if (this.CURSOR) {
// Different field types show different cursor hints.
this.borderRect_.style.cursor = this.CURSOR;
}
this.setText(text);
};
/**
* Non-breaking space.
*/
Blockly.Field.NBSP = '\u00A0';
/**
* Install this field on a block.
* @param {!Blockly.Block} block The block containing this field.
*/
Blockly.Field.prototype.init = function(block) {
if (this.sourceBlock_) {
throw 'Field has already been initialized once.';
}
this.sourceBlock_ = block;
this.group_.setAttribute('class',
block.editable ? 'blocklyEditableText' : 'blocklyNonEditableText');
block.svg_.svgGroup_.appendChild(this.group_);
if (block.editable) {
Blockly.bindEvent_(this.borderRect_, 'mouseup', this, this.onMouseUp_);
}
};
/**
* Destroy all DOM objects belonging to this editable field.
*/
Blockly.Field.prototype.destroy = function() {
this.group_.parentNode.removeChild(this.group_);
this.group_ = null;
this.textElement_ = null;
this.borderRect_ = null;
};
/**
* Sets whether this editable field is visible or not.
* @param {boolean} visible True if visible.
*/
Blockly.Field.prototype.setVisible = function(visible) {
this.getRootElement().style.display = visible ? 'block' : 'none';
};
/**
* Gets the group element for this editable field.
* Used for measuring the size and for positioning.
* @return {!Element} The group element.
*/
Blockly.Field.prototype.getRootElement = function() {
return this.group_;
};
/**
* Draws the border in the correct location.
* Returns the resulting bounding box.
* @return {!Object} Object containing width/height/x/y properties.
*/
Blockly.Field.prototype.render = function() {
var bBox = this.textElement_.getBBox();
if (bBox.height == 0) {
bBox.height = 18;
}
var width = bBox.width + Blockly.BlockSvg.SEP_SPACE_X;
var height = bBox.height;
var left = bBox.x - Blockly.BlockSvg.SEP_SPACE_X / 2;
var top = bBox.y;
this.borderRect_.setAttribute('width', width);
this.borderRect_.setAttribute('height', height);
this.borderRect_.setAttribute('x', left);
this.borderRect_.setAttribute('y', top);
var path = 'M ' + (left + width) + ',' + top;
path += ' v ' + height + ' h -' + width;
this.highlight_.setAttribute('d', path);
return bBox;
};
/**
* Returns the width of the title.
* @return {number} Width.
*/
Blockly.Field.prototype.width = function() {
var bBox = this.render();
if (bBox.width == -Infinity) {
// Opera has trouble with bounding boxes around empty objects.
return 0;
}
return bBox.width;
};
/**
* Set the text in this field. Trigger a rerender of the source block.
* @param {string} text New text.
*/
Blockly.Field.prototype.setText = function(text) {
this.text_ = text;
// Empty the text element.
Blockly.removeChildren_(this.textElement_);
// Replace whitespace with non-breaking spaces so the text doesn't collapse.
text = text.replace(/\s/g, Blockly.Field.NBSP);
if (!text) {
// Prevent the field from disappearing if empty.
text = Blockly.Field.NBSP;
}
var textNode = Blockly.svgDoc.createTextNode(text);
this.textElement_.appendChild(textNode);
if (this.sourceBlock_ && this.sourceBlock_.rendered) {
this.sourceBlock_.render();
this.sourceBlock_.bumpNeighbours_();
}
};
/**
* Get the text from this field.
* @return {string} Current text.
*/
Blockly.Field.prototype.getText = function() {
return this.text_;
};
/**
* Handle a mouse up event on an editable field.
* @param {!Event} e Mouse up event.
* @private
*/
Blockly.Field.prototype.onMouseUp_ = function(e) {
if (e.button == 2) {
// Right-click.
return;
} else if (Blockly.Block.dragMode_ == 2) {
// Drag operation is concluding. Don't open the editor.
return;
}
// Non-abstract sub-classes must define a showEditor_ method.
this.showEditor_();
};
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
File added
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment