UNPKG

cloud-blocks

Version:

Cloud Blocks is a library for building scratch computing interfaces with Luxrobo MODI.

701 lines (668 loc) 17.4 kB
/** * @license * Visual Blocks Editor * * Copyright 2016 Massachusetts Institute of Technology * All rights reserved. * * 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. */ 'use strict'; goog.provide('Blockly.Blocks.data'); goog.provide('Blockly.Constants.Data'); goog.require('Blockly.Blocks'); goog.require('Blockly.Colours'); goog.require('Blockly.constants'); goog.require('Blockly.ScratchBlocks.VerticalExtensions'); Blockly.Blocks['data_variable'] = { /** * Block of Variables * @this Blockly.Block */ init: function () { this.jsonInit({ message0: '%1', lastDummyAlign0: 'CENTRE', args0: [ { type: 'field_variable_getter', text: '', name: 'VARIABLE', variableType: '' } ], category: Blockly.Categories.data, checkboxInFlyout: true, extensions: [ 'contextMenu_getVariableBlock', 'colours_data', 'output_string' ] }); } }; Blockly.Blocks['data_setvariableto'] = { /** * Block to set variable to a certain value * @this Blockly.Block */ init: function () { this.jsonInit({ message0: Blockly.Msg.DATA_SETVARIABLETO, args0: [ { type: 'field_variable', name: 'VARIABLE' }, { type: 'input_value', name: 'VALUE' } ], category: Blockly.Categories.data, extensions: ['colours_data', 'shape_statement'] }); } }; Blockly.Blocks['data_changevariableby'] = { /** * Block to change variable by a certain value * @this Blockly.Block */ init: function () { this.jsonInit({ message0: Blockly.Msg.DATA_CHANGEVARIABLEBY, args0: [ { type: 'field_variable', name: 'VARIABLE' }, { type: 'input_value', name: 'VALUE' } ], category: Blockly.Categories.data, extensions: ['colours_data', 'shape_statement'] }); } }; Blockly.Blocks['data_showvariable'] = { /** * Block to show a variable * @this Blockly.Block */ init: function () { this.jsonInit({ message0: Blockly.Msg.DATA_SHOWVARIABLE, args0: [ { type: 'field_variable', name: 'VARIABLE' } ], previousStatement: null, nextStatement: null, category: Blockly.Categories.data, colour: Blockly.Colours.data.primary, colourSecondary: Blockly.Colours.data.secondary, colourTertiary: Blockly.Colours.data.tertiary }); } }; Blockly.Blocks['data_hidevariable'] = { /** * Block to hide a variable * @this Blockly.Block */ init: function () { this.jsonInit({ message0: Blockly.Msg.DATA_HIDEVARIABLE, args0: [ { type: 'field_variable', name: 'VARIABLE' } ], previousStatement: null, nextStatement: null, category: Blockly.Categories.data, colour: Blockly.Colours.data.primary, colourSecondary: Blockly.Colours.data.secondary, colourTertiary: Blockly.Colours.data.tertiary }); } }; Blockly.Blocks['data_listcontents'] = { /** * List reporter. * @this Blockly.Block */ init: function () { this.jsonInit({ message0: '%1', args0: [ { type: 'field_variable_getter', text: '', name: 'LIST', variableType: Blockly.LIST_VARIABLE_TYPE } ], category: Blockly.Categories.dataLists, extensions: [ 'contextMenu_getListBlock', 'colours_data_lists', 'output_string' ], checkboxInFlyout: true }); } }; Blockly.Blocks['data_listindexall'] = { /** * List index menu, with all option. * @this Blockly.Block */ init: function () { this.jsonInit({ message0: '%1', args0: [ { type: 'field_numberdropdown', name: 'INDEX', value: '1', min: 1, precision: 1, options: [ ['1', '1'], [Blockly.Msg.DATA_INDEX_LAST, 'last'], [Blockly.Msg.DATA_INDEX_ALL, 'all'] ] } ], category: Blockly.Categories.data, extensions: ['colours_textfield', 'output_string'] }); } }; Blockly.Blocks['data_listindexrandom'] = { /** * List index menu, with random option. * @this Blockly.Block */ init: function () { this.jsonInit({ message0: '%1', args0: [ { type: 'field_numberdropdown', name: 'INDEX', value: '1', min: 1, precision: 1, options: [ ['1', '1'], [Blockly.Msg.DATA_INDEX_LAST, 'last'], [Blockly.Msg.DATA_INDEX_RANDOM, 'random'] ] } ], category: Blockly.Categories.data, extensions: ['colours_textfield', 'output_string'] }); } }; Blockly.Blocks['data_addtolist'] = { /** * Block to add item to list. * @this Blockly.Block */ init: function () { this.jsonInit({ message0: Blockly.Msg.DATA_ADDTOLIST, args0: [ { type: 'input_value', name: 'ITEM' }, { type: 'field_variable', name: 'LIST', variableTypes: [Blockly.LIST_VARIABLE_TYPE] } ], category: Blockly.Categories.dataLists, extensions: ['colours_data_lists', 'shape_statement'] }); } }; Blockly.Blocks['data_deleteoflist'] = { /** * Block to delete item from list. * @this Blockly.Block */ init: function () { this.jsonInit({ message0: Blockly.Msg.DATA_DELETEOFLIST, args0: [ { type: 'input_value', name: 'INDEX' }, { type: 'field_variable', name: 'LIST', variableTypes: [Blockly.LIST_VARIABLE_TYPE] } ], category: Blockly.Categories.dataLists, extensions: ['colours_data_lists', 'shape_statement'] }); } }; Blockly.Blocks['data_deletealloflist'] = { /** * Block to delete all items from list. * @this Blockly.Block */ init: function () { this.jsonInit({ message0: Blockly.Msg.DATA_DELETEALLOFLIST, args0: [ { type: 'field_variable', name: 'LIST', variableTypes: [Blockly.LIST_VARIABLE_TYPE] } ], category: Blockly.Categories.dataLists, extensions: ['colours_data_lists', 'shape_statement'] }); } }; Blockly.Blocks['data_insertatlist'] = { /** * Block to insert item to list. * @this Blockly.Block */ init: function () { this.jsonInit({ message0: Blockly.Msg.DATA_INSERTATLIST, args0: [ { type: 'input_value', name: 'ITEM' }, { type: 'input_value', name: 'INDEX' }, { type: 'field_variable', name: 'LIST', variableTypes: [Blockly.LIST_VARIABLE_TYPE] } ], category: Blockly.Categories.dataLists, extensions: ['colours_data_lists', 'shape_statement'] }); } }; Blockly.Blocks['data_replaceitemoflist'] = { /** * Block to insert item to list. * @this Blockly.Block */ init: function () { this.jsonInit({ message0: Blockly.Msg.DATA_REPLACEITEMOFLIST, args0: [ { type: 'input_value', name: 'INDEX' }, { type: 'field_variable', name: 'LIST', variableTypes: [Blockly.LIST_VARIABLE_TYPE] }, { type: 'input_value', name: 'ITEM' } ], category: Blockly.Categories.dataLists, extensions: ['colours_data_lists', 'shape_statement'] }); } }; Blockly.Blocks['data_itemoflist'] = { /** * Block for reporting item of list. * @this Blockly.Block */ init: function () { this.jsonInit({ message0: Blockly.Msg.DATA_ITEMOFLIST, args0: [ { type: 'input_value', name: 'INDEX' }, { type: 'field_variable', name: 'LIST', variableTypes: [Blockly.LIST_VARIABLE_TYPE] } ], output: null, category: Blockly.Categories.dataLists, extensions: ['colours_data_lists'], outputShape: Blockly.OUTPUT_SHAPE_ROUND }); } }; Blockly.Blocks['data_itemnumoflist'] = { /** * Block for reporting the item # of a string in a list. * @this Blockly.Block */ init: function () { this.jsonInit({ message0: Blockly.Msg.DATA_ITEMNUMOFLIST, args0: [ { type: 'input_value', name: 'ITEM' }, { type: 'field_variable', name: 'LIST', variableTypes: [Blockly.LIST_VARIABLE_TYPE] } ], output: null, category: Blockly.Categories.dataLists, extensions: ['colours_data_lists'], outputShape: Blockly.OUTPUT_SHAPE_ROUND }); } }; Blockly.Blocks['data_lengthoflist'] = { /** * Block for reporting length of list. * @this Blockly.Block */ init: function () { this.jsonInit({ message0: Blockly.Msg.DATA_LENGTHOFLIST, args0: [ { type: 'field_variable', name: 'LIST', variableTypes: [Blockly.LIST_VARIABLE_TYPE] } ], category: Blockly.Categories.dataLists, extensions: ['colours_data_lists', 'output_number'] }); } }; Blockly.Blocks['data_listcontainsitem'] = { /** * Block to report whether list contains item. * @this Blockly.Block */ init: function () { this.jsonInit({ message0: Blockly.Msg.DATA_LISTCONTAINSITEM, args0: [ { type: 'field_variable', name: 'LIST', variableTypes: [Blockly.LIST_VARIABLE_TYPE] }, { type: 'input_value', name: 'ITEM' } ], category: Blockly.Categories.dataLists, extensions: ['colours_data_lists', 'output_boolean'] }); } }; Blockly.Blocks['data_showlist'] = { /** * Block to show a list. * @this Blockly.Block */ init: function () { this.jsonInit({ message0: Blockly.Msg.DATA_SHOWLIST, args0: [ { type: 'field_variable', name: 'LIST', variableTypes: [Blockly.LIST_VARIABLE_TYPE] } ], category: Blockly.Categories.dataLists, extensions: ['colours_data_lists', 'shape_statement'] }); } }; Blockly.Blocks['data_hidelist'] = { /** * Block to hide a list. * @this Blockly.Block */ init: function () { this.jsonInit({ message0: Blockly.Msg.DATA_HIDELIST, args0: [ { type: 'field_variable', name: 'LIST', variableTypes: [Blockly.LIST_VARIABLE_TYPE] } ], category: Blockly.Categories.dataLists, extensions: ['colours_data_lists', 'shape_statement'] }); } }; /** * Mixin to add a context menu for a data_variable block. It adds one item for * each variable defined on the workspace. * @mixin * @augments Blockly.Block * @package * @readonly */ Blockly.Constants.Data.CUSTOM_CONTEXT_MENU_GET_VARIABLE_MIXIN = { /** * Add context menu option to change the selected variable. * @param {!Array} options List of menu options to add to. * @this Blockly.Block */ customContextMenu: function (options) { var fieldName = 'VARIABLE'; if (this.isCollapsed()) { return; } var currentVarName = this.getField(fieldName).text_; if (!this.isInFlyout) { var variablesList = this.workspace.getVariablesOfType(''); variablesList.sort(function (a, b) { return Blockly.scratchBlocksUtils.compareStrings(a.name, b.name); }); for (var i = 0; i < variablesList.length; i++) { var varName = variablesList[i].name; if (varName == currentVarName) continue; var option = { enabled: true }; option.text = varName; option.callback = Blockly.Constants.Data.VARIABLE_OPTION_CALLBACK_FACTORY( this, variablesList[i].getId(), fieldName ); options.push(option); } } else { var renameOption = { text: Blockly.Msg.RENAME_VARIABLE, enabled: true, callback: Blockly.Constants.Data.RENAME_OPTION_CALLBACK_FACTORY( this, fieldName ) }; var deleteOption = { text: Blockly.Msg.DELETE_VARIABLE.replace('%1', currentVarName), enabled: true, callback: Blockly.Constants.Data.DELETE_OPTION_CALLBACK_FACTORY( this, fieldName ) }; options.push(renameOption); options.push(deleteOption); } } }; Blockly.Extensions.registerMixin( 'contextMenu_getVariableBlock', Blockly.Constants.Data.CUSTOM_CONTEXT_MENU_GET_VARIABLE_MIXIN ); /** * Mixin to add a context menu for a data_listcontents block. It adds one item for * each list defined on the workspace. * @mixin * @augments Blockly.Block * @package * @readonly */ Blockly.Constants.Data.CUSTOM_CONTEXT_MENU_GET_LIST_MIXIN = { /** * Add context menu option to change the selected list. * @param {!Array} options List of menu options to add to. * @this Blockly.Block */ customContextMenu: function (options) { var fieldName = 'LIST'; if (this.isCollapsed()) { return; } var currentVarName = this.getField(fieldName).text_; if (!this.isInFlyout) { var variablesList = this.workspace.getVariablesOfType('list'); variablesList.sort(function (a, b) { return Blockly.scratchBlocksUtils.compareStrings(a.name, b.name); }); for (var i = 0; i < variablesList.length; i++) { var varName = variablesList[i].name; if (varName == currentVarName) continue; var option = { enabled: true }; option.text = varName; option.callback = Blockly.Constants.Data.VARIABLE_OPTION_CALLBACK_FACTORY( this, variablesList[i].getId(), fieldName ); options.push(option); } } else { var renameOption = { text: Blockly.Msg.RENAME_LIST, enabled: true, callback: Blockly.Constants.Data.RENAME_OPTION_CALLBACK_FACTORY( this, fieldName ) }; var deleteOption = { text: Blockly.Msg.DELETE_LIST.replace('%1', currentVarName), enabled: true, callback: Blockly.Constants.Data.DELETE_OPTION_CALLBACK_FACTORY( this, fieldName ) }; options.push(renameOption); options.push(deleteOption); } } }; Blockly.Extensions.registerMixin( 'contextMenu_getListBlock', Blockly.Constants.Data.CUSTOM_CONTEXT_MENU_GET_LIST_MIXIN ); /** * Callback factory for dropdown menu options associated with a variable getter * block. Each variable on the workspace gets its own item in the dropdown * menu, and clicking on that item changes the text of the field on the source * block. * @param {!Blockly.Block} block The block to update. * @param {string} id The id of the variable to set on this block. * @param {string} fieldName The name of the field to update on the block. * @return {!function()} A function that updates the block with the new name. */ Blockly.Constants.Data.VARIABLE_OPTION_CALLBACK_FACTORY = function ( block, id, fieldName ) { return function () { var variableField = block.getField(fieldName); if (!variableField) { console.log('Tried to get a variable field on the wrong type of block.'); } variableField.setValue(id); }; }; /** * Callback for rename variable dropdown menu option associated with a * variable getter block. * @param {!Blockly.Block} block The block with the variable to rename. * @param {string} fieldName The name of the field to inspect on the block. * @return {!function()} A function that renames the variable. */ Blockly.Constants.Data.RENAME_OPTION_CALLBACK_FACTORY = function ( block, fieldName ) { return function () { var workspace = block.workspace; var variable = block.getField(fieldName).getVariable(); Blockly.Variables.renameVariable(workspace, variable); }; }; /** * Callback for delete variable dropdown menu option associated with a * variable getter block. * @param {!Blockly.Block} block The block with the variable to delete. * @param {string} fieldName The name of the field to inspect on the block. * @return {!function()} A function that deletes the variable. */ Blockly.Constants.Data.DELETE_OPTION_CALLBACK_FACTORY = function ( block, fieldName ) { return function () { var workspace = block.workspace; var variable = block.getField(fieldName).getVariable(); workspace.deleteVariableById(variable.getId()); }; };