Skip to content

Add a context menu to the list getter block #1749

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 24, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 73 additions & 13 deletions blocks_vertical/data.js
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ Blockly.Blocks['data_listcontents'] = {
}
],
"category": Blockly.Categories.dataLists,
"extensions": ["colours_data_lists", "output_string"],
"extensions": ["contextMenu_getListBlock", "colours_data_lists", "output_string"],
"checkboxInFlyout": true
});
}
Expand Down Expand Up @@ -509,12 +509,12 @@ Blockly.Blocks['data_hidelist'] = {
*/
Blockly.Constants.Data.CUSTOM_CONTEXT_MENU_GET_VARIABLE_MIXIN = {
/**
* Add context menu option to create getter block for the loop's variable.
* (customContextMenu support limited to web BlockSvg.)
* 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;
}
Expand All @@ -526,20 +526,22 @@ Blockly.Constants.Data.CUSTOM_CONTEXT_MENU_GET_VARIABLE_MIXIN = {

option.callback =
Blockly.Constants.Data.VARIABLE_OPTION_CALLBACK_FACTORY(this,
option.text);
option.text, fieldName);
options.push(option);
}
} else {
var renameOption = {
text: Blockly.Msg.RENAME_VARIABLE,
enabled: true,
callback: Blockly.Constants.Data.RENAME_OPTION_CALLBACK_FACTORY(this)
callback: Blockly.Constants.Data.RENAME_OPTION_CALLBACK_FACTORY(this,
fieldName)
};
var name = this.getField('VARIABLE').text_;
var name = this.getField(fieldName).text_;
var deleteOption = {
text: Blockly.Msg.DELETE_VARIABLE.replace('%1', name),
enabled: true,
callback: Blockly.Constants.Data.DELETE_OPTION_CALLBACK_FACTORY(this)
callback: Blockly.Constants.Data.DELETE_OPTION_CALLBACK_FACTORY(this,
fieldName)
};
options.push(renameOption);
options.push(deleteOption);
Expand All @@ -550,18 +552,72 @@ Blockly.Constants.Data.CUSTOM_CONTEXT_MENU_GET_VARIABLE_MIXIN = {
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;
}
if (!this.isInFlyout) {
var variablesList = this.workspace.getVariablesOfType('list');
for (var i = 0; i < variablesList.length; i++) {
var option = {enabled: true};
option.text = variablesList[i].name;

option.callback =
Blockly.Constants.Data.VARIABLE_OPTION_CALLBACK_FACTORY(this,
option.text, 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 name = this.getField(fieldName).text_;
var deleteOption = {
text: Blockly.Msg.DELETE_LIST.replace('%1', name),
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} name The new name to display on the 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, name) {
Blockly.Constants.Data.VARIABLE_OPTION_CALLBACK_FACTORY = function(block,
name, fieldName) {
return function() {
var variableField = block.getField('VARIABLE');
var variableField = block.getField(fieldName);
if (!variableField) {
console.log("Tried to get a variable field on the wrong type of block.");
}
Expand All @@ -573,12 +629,14 @@ Blockly.Constants.Data.VARIABLE_OPTION_CALLBACK_FACTORY = function(block, name)
* 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) {
Blockly.Constants.Data.RENAME_OPTION_CALLBACK_FACTORY = function(block,
fieldName) {
return function() {
var workspace = block.workspace;
var variable = block.getField('VARIABLE').getVariable();
var variable = block.getField(fieldName).getVariable();
Blockly.Variables.renameVariable(workspace, variable);
};
};
Expand All @@ -587,12 +645,14 @@ Blockly.Constants.Data.RENAME_OPTION_CALLBACK_FACTORY = function(block) {
* 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) {
Blockly.Constants.Data.DELETE_OPTION_CALLBACK_FACTORY = function(block,
fieldName) {
return function() {
var workspace = block.workspace;
var variable = block.getField('VARIABLE').getVariable();
var variable = block.getField(fieldName).getVariable();
workspace.deleteVariableById(variable.getId());
};
};
2 changes: 2 additions & 0 deletions msg/messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,8 @@ Blockly.Msg.LIST_ALREADY_EXISTS = 'A list named "%1" already exists.';
Blockly.Msg.RENAME_LIST_TITLE = 'Rename all "%1" lists to:';
Blockly.Msg.RENAME_LIST_MODAL_TITLE = 'Rename List';
Blockly.Msg.DEFAULT_LIST_ITEM = 'thing';
Blockly.Msg.DELETE_LIST = 'Delete the "%1" list';
Blockly.Msg.RENAME_LIST = 'Rename list';

// Broadcast Messages
// @todo Remove these once fully managed by Scratch VM / Scratch GUI
Expand Down