Create variables from the flyout

This commit is contained in:
Rachel Fenichel 2016-07-01 15:51:59 -07:00
parent ef4882d90d
commit 13c6c63daa
7 changed files with 117 additions and 51 deletions

View file

@ -110,7 +110,6 @@ Blockly.FieldVariable.dropdownCreate = function() {
}
variableList.sort(goog.string.caseInsensitiveCompare);
variableList.push(Blockly.Msg.RENAME_VARIABLE);
variableList.push(Blockly.Msg.NEW_VARIABLE);
variableList.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.
@ -123,8 +122,8 @@ Blockly.FieldVariable.dropdownCreate = function() {
/**
* Event handler for a change in variable name.
* Special case the 'New variable...' and 'Rename variable...' options.
* In both of these special cases, prompt the user for a new name.
* Special case the 'Rename variable...' and 'Delete variable...' options.
* In the rename case, prompt the user for a new name.
* @param {string} text The selected dropdown menu option.
* @return {null|undefined|string} An acceptable new variable name, or null if
* change is to be either aborted (cancel button) or has been already
@ -132,40 +131,17 @@ Blockly.FieldVariable.dropdownCreate = function() {
* @this {!Blockly.FieldVariable}
*/
Blockly.FieldVariable.classValidator = function(text) {
function promptName(promptText, defaultText) {
Blockly.hideChaff();
var newVar = window.prompt(promptText, defaultText);
// Merge runs of whitespace. Strip leading and trailing whitespace.
// Beyond this, all names are legal.
if (newVar) {
newVar = newVar.replace(/[\s\xa0]+/g, ' ').replace(/^ | $/g, '');
if (newVar == Blockly.Msg.RENAME_VARIABLE ||
newVar == Blockly.Msg.NEW_VARIABLE) {
// Ok, not ALL names are legal...
newVar = null;
}
}
return newVar;
}
var workspace = this.sourceBlock_.workspace;
if (text == Blockly.Msg.RENAME_VARIABLE) {
var oldVar = this.getText();
text = promptName(Blockly.Msg.RENAME_VARIABLE_TITLE.replace('%1', oldVar),
oldVar);
Blockly.hideChaff();
text = Blockly.Variables.promptName(
Blockly.Msg.RENAME_VARIABLE_TITLE.replace('%1', oldVar), oldVar);
if (text) {
Blockly.Variables.renameVariable(oldVar, text, workspace);
}
return null;
} else if (text == Blockly.Msg.NEW_VARIABLE) {
text = promptName(Blockly.Msg.NEW_VARIABLE_TITLE, '');
// Since variables are case-insensitive, ensure that if the new variable
// matches with an existing variable, the new case prevails throughout.
if (text) {
Blockly.Variables.renameVariable(text, text, workspace);
return text;
}
return null;
} else if (text == Blockly.Msg.DELETE_VARIABLE.replace('%1', this.getText())) {
}else if (text == Blockly.Msg.DELETE_VARIABLE.replace('%1', this.getText())) {
Blockly.Variables.delete(this.getText(), this.sourceBlock_.workspace);
return null;
}

View file

@ -608,7 +608,8 @@ Blockly.Flyout.prototype.show = function(xmlList) {
}
else if (tagName == 'BUTTON') {
var label = xml.getAttribute('text');
var curButton = new Blockly.FlyoutButton(this.workspace_, label);
var curButton = new Blockly.FlyoutButton(this.workspace_,
this.targetWorkspace_, label);
contents.push({type: 'button', button: curButton});
gaps.push(this.MARGIN);
}

View file

@ -34,16 +34,23 @@ goog.require('goog.math.Coordinate');
* Class for a button in the flyout.
* @param {!Blockly.Workspace} workspace The workspace in which to place this
* button.
* @param {!Blockly.Workspace} targetWorkspace The flyout's target workspace.
* @param {string} text The text to display on the button.
* @constructor
*/
Blockly.FlyoutButton = function(workspace, text) {
Blockly.FlyoutButton = function(workspace, targetWorkspace, text) {
/**
* @type {!Blockly.Workspace}
* @private
*/
this.workspace_ = workspace;
/**
* @type {!Blockly.Workspace}
* @private
*/
this.targetWorkspace_ = targetWorkspace;
/**
* @type {string}
* @private
@ -150,9 +157,10 @@ Blockly.FlyoutButton.prototype.dispose = function() {
* @param {!Event} e Mouse up event.
*/
Blockly.FlyoutButton.prototype.onMouseUp = function(e) {
console.log("Button was clicked");
// Don't scroll the page.
e.preventDefault();
// Don't propagate mousewheel event (zooming).
e.stopPropagation();
Blockly.Variables.createVariable(this.targetWorkspace_);
};

View file

@ -420,6 +420,18 @@ Blockly.Toolbox.prototype.getClientRect = function() {
}
};
/**
* Update the flyout's contents without closing it. Should be used in response
* to a change in one of the dynamic categories, such as variables or
* procedures.
*/
Blockly.Toolbox.prototype.refreshSelection = function() {
var selectedItem = this.tree_.getSelectedItem();
if (selectedItem && selectedItem.blocks) {
this.flyout_.show(selectedItem.blocks);
}
};
// Extending Closure's Tree UI.
/**

View file

@ -110,29 +110,31 @@ Blockly.Variables.flyoutCategory = function(workspace) {
var button = goog.dom.createDom('button');
button.setAttribute('text', 'Create variable');
xmlList.push(button);
for (var i = 0; i < variableList.length; i++) {
if (Blockly.Blocks['variables_set']) {
// <block type="variables_set" gap="8">
// <field name="VAR">item</field>
// </block>
var block = goog.dom.createDom('block');
block.setAttribute('type', 'variables_set');
if (Blockly.Blocks['variables_get']) {
block.setAttribute('gap', 8);
}
var field = goog.dom.createDom('field', null, variableList[i]);
field.setAttribute('name', 'VAR');
block.appendChild(field);
xmlList.push(block);
}
if (Blockly.Blocks['variables_set']) {
// <block type="variables_set" gap="20">
// <field name="VAR">item</field>
// </block>
var block = goog.dom.createDom('block');
block.setAttribute('type', 'variables_set');
if (Blockly.Blocks['variables_get']) {
// <block type="variables_get" gap="24">
block.setAttribute('gap', 20);
}
var field = goog.dom.createDom('field', null, variableList[0]);
field.setAttribute('name', 'VAR');
block.appendChild(field);
xmlList.push(block);
}
for (var i = 0; i < variableList.length; i++) {
if (Blockly.Blocks['variables_get']) {
// <block type="variables_get" gap="8">
// <field name="VAR">item</field>
// </block>
var block = goog.dom.createDom('block');
block.setAttribute('type', 'variables_get');
if (Blockly.Blocks['variables_set']) {
block.setAttribute('gap', 24);
block.setAttribute('gap', 8);
}
var field = goog.dom.createDom('field', null, variableList[i]);
field.setAttribute('name', 'VAR');
@ -244,3 +246,44 @@ Blockly.Variables.delete = function(name, workspace) {
Blockly.Variables.disposeUses(name, workspace);
};
/**
* Create a new variable on the given workspace.
* @param {!Blockly.Workspace} workspace The workspace on which to create the
* variable.
* @return {null|undefined|string} An acceptable new variable name, or null if
* change is to be aborted (cancel button), or undefined if an existing
* variable was chosen.
*/
Blockly.Variables.createVariable = function(workspace) {
var text = Blockly.Variables.promptName(Blockly.Msg.NEW_VARIABLE_TITLE, '');
// Since variables are case-insensitive, ensure that if the new variable
// matches with an existing variable, the new case prevails throughout.
if (text) {
workspace.createVariable(text);
return text;
}
return null;
};
/**
* Prompt the user for a new variable name.
* @param {string} promptText The string of the prompt.
* @param {string} defaultText The default value to show in the prompt's field.
* @return {string|null} The new variable name, or null if the user picked
* something illegal.
*/
Blockly.Variables.promptName = function(promptText, defaultText) {
var newVar = window.prompt(promptText, defaultText);
// Merge runs of whitespace. Strip leading and trailing whitespace.
// Beyond this, all names are legal.
if (newVar) {
newVar = newVar.replace(/[\s\xa0]+/g, ' ').replace(/^ | $/g, '');
if (newVar == Blockly.Msg.RENAME_VARIABLE ||
newVar == Blockly.Msg.NEW_VARIABLE) {
// Ok, not ALL names are legal...
newVar = null;
}
}
return newVar;
};

View file

@ -217,20 +217,33 @@ Blockly.Workspace.prototype.updateVariableList = function() {
/**
* Rename a variable by updating its name in the variable list.
* TODO: #468
* @param {string} oldName Variable to rename.
* @param {string} newName New variable name.
*/
Blockly.Workspace.prototype.renameVariable = function(oldName, newName) {
// Find the old name in the list and replace it.
var variableIndex = this.variableList.indexOf(oldName);
if (variableIndex != -1) {
var newVariableIndex = this.variableList.indexOf(newName);
if (variableIndex != -1 && newVariableIndex == -1) {
this.variableList[variableIndex] = newName;
} else if (variableIndex != -1 && newVariableIndex != -1) {
this.variableList.splice(variableIndex, 1);
} else {
this.variableList.push(newName);
console.log('Tried to rename an non-existent variable.');
}
};
/**
* Create a variables with the given name.
* TODO: #468
* @param {string} name The new variable's name.
*/
Blockly.Workspace.prototype.createVariable = function(name) {
this.variableList.push(name);
};
/**
* Returns the horizontal offset of the workspace.
* Intended for LTR/RTL compatibility in XML.

View file

@ -589,6 +589,19 @@ Blockly.WorkspaceSvg.prototype.paste = function(xmlBlock) {
block.select();
};
/**
* Create a new variable with the given name. Update the flyout to show the new
* variable immediately.
* TODO: #468
* @param {string} name The new variable's name.
*/
Blockly.WorkspaceSvg.prototype.createVariable = function(name) {
Blockly.WorkspaceSvg.superClass_.createVariable.call(this, name);
if (this.toolbox_ && this.toolbox_.flyout_) {
this.toolbox_.refreshSelection();
}
};
/**
* Make a list of all the delete areas for this workspace.
*/