From 6492f2988a0862fc01a8f434e295445e1890840f Mon Sep 17 00:00:00 2001 From: marisaleung Date: Wed, 10 May 2017 12:55:12 -0700 Subject: [PATCH] Assign variable UUID to field_variable dropdown. --- core/constants.js | 16 ++++++++ core/field_variable.js | 83 ++++++++++++++++++++---------------------- core/variable_model.js | 17 ++++++++- core/workspace_svg.js | 4 +- 4 files changed, 73 insertions(+), 47 deletions(-) diff --git a/core/constants.js b/core/constants.js index f69531ee7..b8a63e92c 100644 --- a/core/constants.js +++ b/core/constants.js @@ -236,3 +236,19 @@ Blockly.VARIABLE_CATEGORY_NAME = 'VARIABLE'; * @const {string} */ Blockly.PROCEDURE_CATEGORY_NAME = 'PROCEDURE'; + +/** + * String for use in the dropdown created in field_variable. + * This string indicates that this option in the dropdown is 'Rename + * variable...' and if selected, should trigger the prompt to rename a variable. + * @const {string} + */ +Blockly.RENAME_VARIABLE_ID = 'RENAME_VARIABLE_ID'; + +/** + * String for use in the dropdown created in field_variable. + * This string indicates that this option in the dropdown is 'Delete the "%1" + * variable' and if selected, should trigger the prompt to delete a variable. + * @const {string} + */ +Blockly.DELETE_VARIABLE_ID = 'DELETE_VARIABLE_ID'; diff --git a/core/field_variable.js b/core/field_variable.js index 8f8b54284..36761760d 100644 --- a/core/field_variable.js +++ b/core/field_variable.js @@ -49,21 +49,6 @@ Blockly.FieldVariable = function(varname, opt_validator) { }; goog.inherits(Blockly.FieldVariable, Blockly.FieldDropdown); -/** - * The menu item index for the rename variable option. - * @type {number} - * @private - */ -Blockly.FieldVariable.prototype.renameVarItemIndex_ = -1; - -/** - * The menu item index for the delete variable option. - * @type {number} - * @private - */ -Blockly.FieldVariable.prototype.deleteVarItemIndex_ = -1; - - /** * Install this dropdown on a block. */ @@ -134,37 +119,41 @@ Blockly.FieldVariable.prototype.setValue = function(newValue) { * @this {Blockly.FieldVariable} */ Blockly.FieldVariable.dropdownCreate = function() { - var variableNameList = []; - if (this.sourceBlock_ && this.sourceBlock_.workspace) { + var variableModelList = []; + var name = this.getText(); + // Don't create a new variable if there is nothing selected. + var createSelectedVariable = name ? true : false; + var workspace = null; + if (this.sourceBlock_) { + workspace = this.sourceBlock_.workspace; + } + + if (workspace) { // Get a copy of the list, so that adding rename and new variable options // doesn't modify the workspace's list. - - var variableModelList = this.sourceBlock_.workspace.getVariablesOfType(''); - for (var i = 0; i < variableModelList.length; i++) { - variableNameList.push(variableModelList[i].name); + var variableModelList = workspace.getVariablesOfType(''); + for (var i = 0; i < variableModelList.length; i++){ + if (createSelectedVariable && + goog.string.caseInsensitiveEquals(variableModelList[i].name, name)) { + createSelectedVariable = false; + break; + } } } // Ensure that the currently selected variable is an option. - var name = this.getText(); - if (name && variableNameList.indexOf(name) == -1) { - variableNameList.push(name); + if (createSelectedVariable && workspace) { + var newVar = workspace.createVariable(name); + variableModelList.push(newVar); } - variableNameList.sort(goog.string.caseInsensitiveCompare); - - this.renameVarItemIndex_ = variableNameList.length; - variableNameList.push(Blockly.Msg.RENAME_VARIABLE); - - this.deleteVarItemIndex_ = variableNameList.length; - variableNameList.push(Blockly.Msg.DELETE_VARIABLE.replace('%1', name)); - // Variables are not language-specific, use the name as both the user-facing - // text and the internal representation. + variableModelList.sort(Blockly.VariableModel.compareByName); var options = []; - for (var i = 0; i < variableNameList.length; i++) { - // TODO(marisaleung): Set options[i] to [name, uuid]. This requires - // changes where the variable gets set since the initialized value would be - // id. - options[i] = [variableNameList[i], variableNameList[i]]; + for (var i = 0; i < variableModelList.length; i++) { + // Set the uuid as the internal representation of the variable. + options[i] = [variableModelList[i].name, variableModelList[i].getId()]; } + options.push([Blockly.Msg.RENAME_VARIABLE, Blockly.RENAME_VARIABLE_ID]); + options.push([Blockly.Msg.DELETE_VARIABLE.replace('%1', name), + Blockly.DELETE_VARIABLE_ID]); return options; }; @@ -176,11 +165,18 @@ Blockly.FieldVariable.dropdownCreate = function() { * @param {!goog.ui.MenuItem} menuItem The MenuItem selected within menu. */ Blockly.FieldVariable.prototype.onItemSelected = function(menu, menuItem) { - var itemText = menuItem.getValue(); - if (this.sourceBlock_) { + var id = menuItem.getValue(); + // TODO(marisaleung): change setValue() to take in an id as the parameter. + // Then remove itemText. + var itemText; + if (this.sourceBlock_ && this.sourceBlock_.workspace) { var workspace = this.sourceBlock_.workspace; - if (this.renameVarItemIndex_ >= 0 && - menu.getChildAt(this.renameVarItemIndex_) === menuItem) { + var variable = workspace.getVariableById(id); + // If the item selected is a variable, set itemText to the variable name. + if (variable) { + itemText = variable.name; + } + else if (id == Blockly.RENAME_VARIABLE_ID) { // Rename variable. var oldName = this.getText(); Blockly.hideChaff(); @@ -192,8 +188,7 @@ Blockly.FieldVariable.prototype.onItemSelected = function(menu, menuItem) { } }); return; - } else if (this.deleteVarItemIndex_ >= 0 && - menu.getChildAt(this.deleteVarItemIndex_) === menuItem) { + } else if (id == Blockly.DELETE_VARIABLE_ID) { // Delete variable. workspace.deleteVariable(this.getText()); return; diff --git a/core/variable_model.js b/core/variable_model.js index 6f705d0bd..e84a76132 100644 --- a/core/variable_model.js +++ b/core/variable_model.js @@ -26,15 +26,18 @@ goog.provide('Blockly.VariableModel'); +goog.require('goog.string'); + + /** * Class for a variable model. - * Holds information for the variable including name, id, and type. + * Holds information for the variable including name, id, and type. * @param {!string} name The name of the variable. This must be unique across * variables and procedures. * @param {?string} opt_type The type of the variable like 'int' or 'string'. * Does not need to be unique. Field_variable can filter variables based on * their type. This will default to '' which is a specific type. - * @param {?string} opt_id The unique id of the variable. This will default to + * @param {?string} opt_id The unique id of the variable. This will default to * a UUID. * @see {Blockly.FieldVariable} * @constructor @@ -73,3 +76,13 @@ Blockly.VariableModel = function(name, opt_type, opt_id) { Blockly.VariableModel.prototype.getId = function() { return this.id_; }; + +/** + * A custom compare function for the VariableModel objects. + * @param {Blockly.VariableModel} var1 First variable to compare. + * @param {Blockly.VariableModel} var2 Second variable to compare. + * @package + */ +Blockly.VariableModel.compareByName = function(var1, var2) { + return goog.string.caseInsensitiveCompare(var1.name, var2.name) +}; diff --git a/core/workspace_svg.js b/core/workspace_svg.js index 067449028..53b4fc30c 100644 --- a/core/workspace_svg.js +++ b/core/workspace_svg.js @@ -872,13 +872,15 @@ Blockly.WorkspaceSvg.prototype.paste = function(xmlBlock) { * variable immediately. * TODO: #468 * @param {string} name The new variable's name. + * @return {?Blockly.VariableModel} The newly created variable. */ Blockly.WorkspaceSvg.prototype.createVariable = function(name) { - Blockly.WorkspaceSvg.superClass_.createVariable.call(this, name); + var newVar = Blockly.WorkspaceSvg.superClass_.createVariable.call(this, name); // Don't refresh the toolbox if there's a drag in progress. if (this.toolbox_ && this.toolbox_.flyout_ && !Blockly.Flyout.startFlyout_) { this.toolbox_.refreshSelection(); } + return newVar; }; /**