cloud-blocks
Version:
Cloud Blocks is a library for building scratch computing interfaces with Luxrobo MODI.
573 lines (537 loc) • 18.5 kB
JavaScript
/**
* @license
* Visual Blocks Editor
*
* Copyright 2017 Google Inc.
* https://developers.google.com/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 Data Flyout components including variable and list blocks.
* @author marisaleung@google.com (Marisa Leung)
*/
'use strict';
/**
* @name Blockly.DataCategory
* @namespace
**/
goog.provide('Blockly.DataCategory');
goog.require('Blockly.Blocks');
goog.require('Blockly.VariableModel');
goog.require('Blockly.Variables');
goog.require('Blockly.Workspace');
/**
* Construct the blocks required by the flyout for the variable category.
* @param {!Blockly.Workspace} workspace The workspace containing variables.
* @return {!Array.} Array of XML block elements.
*/
Blockly.DataCategory = function (workspace) {
var variableModelList = workspace.getVariablesOfType('');
variableModelList.sort(Blockly.VariableModel.compareByName);
var xmlList = [];
Blockly.DataCategory.addCreateButton(xmlList, workspace, 'VARIABLE');
for (var i = 0; i < variableModelList.length; i++) {
Blockly.DataCategory.addDataVariable(xmlList, variableModelList[i]);
}
if (variableModelList.length > 0) {
xmlList[xmlList.length - 1].setAttribute('gap', 24);
var firstVariable = variableModelList[0];
Blockly.DataCategory.addSetVariableTo(xmlList, firstVariable);
Blockly.DataCategory.addChangeVariableBy(xmlList, firstVariable);
}
// Now add list variables to the flyout
// Blockly.DataCategory.addCreateButton(xmlList, workspace, 'LIST');
variableModelList = workspace.getVariablesOfType(Blockly.LIST_VARIABLE_TYPE);
variableModelList.sort(Blockly.VariableModel.compareByName);
for (var i = 0; i < variableModelList.length; i++) {
Blockly.DataCategory.addDataList(xmlList, variableModelList[i]);
}
if (variableModelList.length > 0) {
xmlList[xmlList.length - 1].setAttribute('gap', 24);
var firstVariable = variableModelList[0];
Blockly.DataCategory.addAddToList(xmlList, firstVariable);
Blockly.DataCategory.addSep(xmlList);
Blockly.DataCategory.addDeleteOfList(xmlList, firstVariable);
Blockly.DataCategory.addDeleteAllOfList(xmlList, firstVariable);
Blockly.DataCategory.addInsertAtList(xmlList, firstVariable);
Blockly.DataCategory.addReplaceItemOfList(xmlList, firstVariable);
Blockly.DataCategory.addSep(xmlList);
Blockly.DataCategory.addItemOfList(xmlList, firstVariable);
Blockly.DataCategory.addItemNumberOfList(xmlList, firstVariable);
Blockly.DataCategory.addLengthOfList(xmlList, firstVariable);
Blockly.DataCategory.addListContainsItem(xmlList, firstVariable);
Blockly.DataCategory.addSep(xmlList);
Blockly.DataCategory.addShowList(xmlList, firstVariable);
Blockly.DataCategory.addHideList(xmlList, firstVariable);
}
return xmlList;
};
/**
* Construct and add a data_variable block to xmlList.
* @param {!Array.} xmlList Array of XML block elements.
* @param {?Blockly.VariableModel} variable Variable to select in the field.
*/
Blockly.DataCategory.addDataVariable = function (xmlList, variable) {
// <block id="variableId" type="data_variable">
// <field name="VARIABLE">variablename</field>
// </block>
Blockly.DataCategory.addBlock(xmlList, variable, 'data_variable', 'VARIABLE');
// In the flyout, this ID must match variable ID for monitor syncing reasons
xmlList[xmlList.length - 1].setAttribute('id', variable.getId());
};
/**
* Construct and add a data_setvariableto block to xmlList.
* @param {!Array.} xmlList Array of XML block elements.
* @param {?Blockly.VariableModel} variable Variable to select in the field.
*/
Blockly.DataCategory.addSetVariableTo = function (xmlList, variable) {
// <block type="data_setvariableto" gap="20">
// <value name="VARIABLE">
// <shadow type="data_variablemenu"></shadow>
// </value>
// <value name="VALUE">
// <shadow type="text">
// <field name="TEXT">0</field>
// </shadow>
// </value>
// </block>
Blockly.DataCategory.addBlock(
xmlList,
variable,
'data_setvariableto',
'VARIABLE',
['VALUE', 'math_number', 0]
);
};
/**
* Construct and add a data_changevariableby block to xmlList.
* @param {!Array.} xmlList Array of XML block elements.
* @param {?Blockly.VariableModel} variable Variable to select in the field.
*/
Blockly.DataCategory.addChangeVariableBy = function (xmlList, variable) {
// <block type="data_changevariableby">
// <value name="VARIABLE">
// <shadow type="data_variablemenu"></shadow>
// </value>
// <value name="VALUE">
// <shadow type="math_number">
// <field name="NUM">1</field>
// </shadow>
// </value>
// </block>
Blockly.DataCategory.addBlock(
xmlList,
variable,
'data_changevariableby',
'VARIABLE',
['VALUE', 'math_number', 1]
);
};
/**
* Construct and add a data_showVariable block to xmlList.
* @param {!Array.} xmlList Array of XML block elements.
* @param {?Blockly.VariableModel} variable Variable to select in the field.
*/
Blockly.DataCategory.addShowVariable = function (xmlList, variable) {
// <block type="data_showvariable">
// <value name="VARIABLE">
// <shadow type="data_variablemenu"></shadow>
// </value>
// </block>
Blockly.DataCategory.addBlock(
xmlList,
variable,
'data_showvariable',
'VARIABLE'
);
};
/**
* Construct and add a data_hideVariable block to xmlList.
* @param {!Array.} xmlList Array of XML block elements.
* @param {?Blockly.VariableModel} variable Variable to select in the field.
*/
Blockly.DataCategory.addHideVariable = function (xmlList, variable) {
// <block type="data_hidevariable">
// <value name="VARIABLE">
// <shadow type="data_variablemenu"></shadow>
// </value>
// </block>
Blockly.DataCategory.addBlock(
xmlList,
variable,
'data_hidevariable',
'VARIABLE'
);
};
/**
* Construct and add a data_listcontents block to xmlList.
* @param {!Array.} xmlList Array of XML block elements.
* @param {?Blockly.VariableModel} variable Variable to select in the field.
*/
Blockly.DataCategory.addDataList = function (xmlList, variable) {
// <block id="variableId" type="data_listcontents">
// <field name="LIST">variablename</field>
// </block>
Blockly.DataCategory.addBlock(xmlList, variable, 'data_listcontents', 'LIST');
// In the flyout, this ID must match variable ID for monitor syncing reasons
xmlList[xmlList.length - 1].setAttribute('id', variable.getId());
};
/**
* Construct and add a data_addtolist block to xmlList.
* @param {!Array.} xmlList Array of XML block elements.
* @param {?Blockly.VariableModel} variable Variable to select in the field.
*/
Blockly.DataCategory.addAddToList = function (xmlList, variable) {
// <block type="data_addtolist">
// <field name="LIST" variabletype="list" id="">variablename</field>
// <value name="ITEM">
// <shadow type="text">
// <field name="TEXT">thing</field>
// </shadow>
// </value>
// </block>
Blockly.DataCategory.addBlock(xmlList, variable, 'data_addtolist', 'LIST', [
'ITEM',
'text',
Blockly.Msg.DEFAULT_LIST_ITEM
]);
};
/**
* Construct and add a data_deleteoflist block to xmlList.
* @param {!Array.} xmlList Array of XML block elements.
* @param {?Blockly.VariableModel} variable Variable to select in the field.
*/
Blockly.DataCategory.addDeleteOfList = function (xmlList, variable) {
// <block type="data_deleteoflist">
// <field name="LIST" variabletype="list" id="">variablename</field>
// <value name="INDEX">
// <shadow type="math_integer">
// <field name="NUM">1</field>
// </shadow>
// </value>
// </block>
Blockly.DataCategory.addBlock(
xmlList,
variable,
'data_deleteoflist',
'LIST',
['INDEX', 'math_integer', 1]
);
};
/**
* Construct and add a data_deleteoflist block to xmlList.
* @param {!Array.} xmlList Array of XML block elements.
* @param {?Blockly.VariableModel} variable Variable to select in the field.
*/
Blockly.DataCategory.addDeleteAllOfList = function (xmlList, variable) {
// <block type="data_deletealloflist">
// <field name="LIST" variabletype="list" id="">variablename</field>
// </block>
Blockly.DataCategory.addBlock(
xmlList,
variable,
'data_deletealloflist',
'LIST'
);
};
/**
* Construct and add a data_insertatlist block to xmlList.
* @param {!Array.} xmlList Array of XML block elements.
* @param {?Blockly.VariableModel} variable Variable to select in the field.
*/
Blockly.DataCategory.addInsertAtList = function (xmlList, variable) {
// <block type="data_insertatlist">
// <field name="LIST" variabletype="list" id="">variablename</field>
// <value name="INDEX">
// <shadow type="math_integer">
// <field name="NUM">1</field>
// </shadow>
// </value>
// <value name="ITEM">
// <shadow type="text">
// <field name="TEXT">thing</field>
// </shadow>
// </value>
// </block>
Blockly.DataCategory.addBlock(
xmlList,
variable,
'data_insertatlist',
'LIST',
['INDEX', 'math_integer', 1],
['ITEM', 'text', Blockly.Msg.DEFAULT_LIST_ITEM]
);
};
/**
* Construct and add a data_replaceitemoflist block to xmlList.
* @param {!Array.} xmlList Array of XML block elements.
* @param {?Blockly.VariableModel} variable Variable to select in the field.
*/
Blockly.DataCategory.addReplaceItemOfList = function (xmlList, variable) {
// <block type="data_replaceitemoflist">
// <field name="LIST" variabletype="list" id="">variablename</field>
// <value name="INDEX">
// <shadow type="math_integer">
// <field name="NUM">1</field>
// </shadow>
// </value>
// <value name="ITEM">
// <shadow type="text">
// <field name="TEXT">thing</field>
// </shadow>
// </value>
// </block>
Blockly.DataCategory.addBlock(
xmlList,
variable,
'data_replaceitemoflist',
'LIST',
['INDEX', 'math_integer', 1],
['ITEM', 'text', Blockly.Msg.DEFAULT_LIST_ITEM]
);
};
/**
* Construct and add a data_itemoflist block to xmlList.
* @param {!Array.} xmlList Array of XML block elements.
* @param {?Blockly.VariableModel} variable Variable to select in the field.
*/
Blockly.DataCategory.addItemOfList = function (xmlList, variable) {
// <block type="data_itemoflist">
// <field name="LIST" variabletype="list" id="">variablename</field>
// <value name="INDEX">
// <shadow type="math_integer">
// <field name="NUM">1</field>
// </shadow>
// </value>
// </block>
Blockly.DataCategory.addBlock(xmlList, variable, 'data_itemoflist', 'LIST', [
'INDEX',
'math_integer',
1
]);
};
/** Construct and add a data_itemnumoflist block to xmlList.
* @param {!Array.} xmlList Array of XML block elements.
* @param {?Blockly.VariableModel} variable Variable to select in the field.
*/
Blockly.DataCategory.addItemNumberOfList = function (xmlList, variable) {
// <block type="data_itemnumoflist">
// <value name="ITEM">
// <shadow type="text">
// <field name="TEXT">thing</field>
// </shadow>
// </value>
// <field name="LIST" variabletype="list" id="">variablename</field>
// </block>
Blockly.DataCategory.addBlock(
xmlList,
variable,
'data_itemnumoflist',
'LIST',
['ITEM', 'text', Blockly.Msg.DEFAULT_LIST_ITEM]
);
};
/**
* Construct and add a data_lengthoflist block to xmlList.
* @param {!Array.} xmlList Array of XML block elements.
* @param {?Blockly.VariableModel} variable Variable to select in the field.
*/
Blockly.DataCategory.addLengthOfList = function (xmlList, variable) {
// <block type="data_lengthoflist">
// <field name="LIST" variabletype="list" id="">variablename</field>
// </block>
Blockly.DataCategory.addBlock(xmlList, variable, 'data_lengthoflist', 'LIST');
};
/**
* Construct and add a data_listcontainsitem block to xmlList.
* @param {!Array.} xmlList Array of XML block elements.
* @param {?Blockly.VariableModel} variable Variable to select in the field.
*/
Blockly.DataCategory.addListContainsItem = function (xmlList, variable) {
// <block type="data_listcontainsitem">
// <field name="LIST" variabletype="list" id="">variablename</field>
// <value name="ITEM">
// <shadow type="text">
// <field name="TEXT">thing</field>
// </shadow>
// </value>
// </block>
Blockly.DataCategory.addBlock(
xmlList,
variable,
'data_listcontainsitem',
'LIST',
['ITEM', 'text', Blockly.Msg.DEFAULT_LIST_ITEM]
);
};
/**
* Construct and add a data_showlist block to xmlList.
* @param {!Array.} xmlList Array of XML block elements.
* @param {?Blockly.VariableModel} variable Variable to select in the field.
*/
Blockly.DataCategory.addShowList = function (xmlList, variable) {
// <block type="data_showlist">
// <field name="LIST" variabletype="list" id="">variablename</field>
// </block>
Blockly.DataCategory.addBlock(xmlList, variable, 'data_showlist', 'LIST');
};
/**
* Construct and add a data_hidelist block to xmlList.
* @param {!Array.} xmlList Array of XML block elements.
* @param {?Blockly.VariableModel} variable Variable to select in the field.
*/
Blockly.DataCategory.addHideList = function (xmlList, variable) {
// <block type="data_hidelist">
// <field name="LIST" variabletype="list" id="">variablename</field>
// </block>
Blockly.DataCategory.addBlock(xmlList, variable, 'data_hidelist', 'LIST');
};
/**
* Construct a create variable button and push it to the xmlList.
* @param {!Array.} xmlList Array of XML block elements.
* @param {Blockly.Workspace} workspace Workspace to register callback to.
* @param {string} type Type of variable this is for. For example, 'LIST' or
* 'VARIABLE'.
*/
Blockly.DataCategory.addCreateButton = function (xmlList, workspace, type) {
var button = goog.dom.createDom('button');
// Set default msg, callbackKey, and callback values for type 'VARIABLE'
var msg = Blockly.Msg.NEW_VARIABLE;
var callbackKey = 'CREATE_VARIABLE';
var callback = function (button) {
Blockly.Variables.createVariable(button.getTargetWorkspace(), null, '');
};
if (type === 'LIST') {
msg = Blockly.Msg.NEW_LIST;
callbackKey = 'CREATE_LIST';
callback = function (button) {
Blockly.Variables.createVariable(
button.getTargetWorkspace(),
null,
Blockly.LIST_VARIABLE_TYPE
);
};
}
button.setAttribute('text', msg);
button.setAttribute('callbackKey', callbackKey);
workspace.registerButtonCallback(callbackKey, callback);
xmlList.push(button);
};
/**
* Construct a variable block with the given variable, blockType, and optional
* value tags. Add the variable block to the given xmlList.
* @param {!Array.} xmlList Array of XML block elements.
* @param {?Blockly.VariableModel} variable Variable to select in the field.
* @param {string} blockType Type of block. For example, 'data_hidelist' or
* data_showlist'.
* @param {string} fieldName Name of field in block. For example: 'VARIABLE' or
* 'LIST'.
* @param {?Array.<string>} opt_value Optional array containing the value name
* and shadow type of value tags.
* @param {?Array.<string>} opt_secondValue Optional array containing the value
* name and shadow type of a second pair of value tags.
*/
Blockly.DataCategory.addBlock = function (
xmlList,
variable,
blockType,
fieldName,
opt_value,
opt_secondValue
) {
if (Blockly.Blocks[blockType]) {
var firstValueField;
var secondValueField;
if (opt_value) {
firstValueField = Blockly.DataCategory.createValue(
opt_value[0],
opt_value[1],
opt_value[2]
);
}
if (opt_secondValue) {
secondValueField = Blockly.DataCategory.createValue(
opt_secondValue[0],
opt_secondValue[1],
opt_secondValue[2]
);
}
var gap = 8;
var blockText =
'<xml>' +
'<block type="' +
blockType +
'" gap="' +
gap +
'">' +
Blockly.Variables.generateVariableFieldXml_(variable, fieldName) +
firstValueField +
secondValueField +
'</block>' +
'</xml>';
var block = Blockly.Xml.textToDom(blockText).firstChild;
xmlList.push(block);
}
};
/**
* Create the text representation of a value dom element with a shadow of the
* indicated type inside.
* @param {string} valueName Name of the value tags.
* @param {string} type The type of the shadow tags.
* @param {string|number} value The default shadow value.
* @return {string} The generated dom element in text.
*/
Blockly.DataCategory.createValue = function (valueName, type, value) {
var fieldName;
switch (valueName) {
case 'ITEM':
fieldName = 'TEXT';
break;
case 'INDEX':
fieldName = 'NUM';
break;
case 'VALUE':
if (type === 'math_number') {
fieldName = 'NUM';
} else {
fieldName = 'TEXT';
}
break;
}
var valueField =
'<value name="' +
valueName +
'">' +
'<shadow type="' +
type +
'">' +
'<field name="' +
fieldName +
'">' +
value +
'</field>' +
'</shadow>' +
'</value>';
return valueField;
};
/**
* Construct a block separator. Add the separator to the given xmlList.
* @param {!Array.} xmlList Array of XML block elements.
*/
Blockly.DataCategory.addSep = function (xmlList) {
var gap = 36;
var sepText = '<xml>' + '<sep gap="' + gap + '"/>' + '</xml>';
var sep = Blockly.Xml.textToDom(sepText).firstChild;
xmlList.push(sep);
};