scratch-blocks/core/field_textdropdown.js
2018-05-02 15:32:28 -07:00

164 lines
5.6 KiB
JavaScript

/**
* @license
* Visual Blocks Editor
*
* Copyright 2013 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 Combination text + drop-down field
* @author tmickel@mit.edu (Tim Mickel)
*/
'use strict';
goog.provide('Blockly.FieldTextDropdown');
goog.require('Blockly.DropDownDiv');
goog.require('Blockly.FieldDropdown');
goog.require('Blockly.FieldTextInput');
goog.require('goog.userAgent');
/**
* Class for a combination text + drop-down field.
* @param {string} text The initial content of the text field.
* @param {(!Array.<!Array.<string>>|!Function)} menuGenerator An array of
* options for a dropdown list, or a function which generates these options.
* @param {Function=} opt_validator An optional function that is called
* to validate any constraints on what the user entered. Takes the new
* text as an argument and returns the accepted text or null to abort
* the change.
* @param {RegExp=} opt_restrictor An optional regular expression to restrict
* typed text to. Text that doesn't match the restrictor will never show
* in the text field.
* @extends {Blockly.FieldTextInput}
* @constructor
*/
Blockly.FieldTextDropdown = function(text, menuGenerator, opt_validator, opt_restrictor) {
this.menuGenerator_ = menuGenerator;
Blockly.FieldDropdown.prototype.trimOptions_.call(this);
Blockly.FieldTextDropdown.superClass_.constructor.call(this, text, opt_validator, opt_restrictor);
this.addArgType('textdropdown');
};
goog.inherits(Blockly.FieldTextDropdown, Blockly.FieldTextInput);
/**
* Construct a FieldTextDropdown from a JSON arg object,
* dereferencing any string table references.
* @param {!Object} element A JSON object with options.
* @returns {!Blockly.FieldTextDropdown} The new field instance.
* @package
* @nocollapse
*/
Blockly.FieldTextDropdown.fromJson = function(element) {
var field =
new Blockly.FieldTextDropdown(element['text'], element['options']);
if (typeof element['spellcheck'] == 'boolean') {
field.setSpellcheck(element['spellcheck']);
}
return field;
};
/**
* Install this text drop-down field on a block.
*/
Blockly.FieldTextDropdown.prototype.init = function() {
if (this.fieldGroup_) {
// Text input + dropdown has already been initialized once.
return;
}
Blockly.FieldTextDropdown.superClass_.init.call(this);
// Add dropdown arrow: "option ▾" (LTR) or "▾ אופציה" (RTL)
// Positioned on render, after text size is calculated.
if (!this.arrow_) {
/** @type {Number} */
this.arrowSize_ = 12;
/** @type {Number} */
this.arrowX_ = 0;
/** @type {Number} */
this.arrowY_ = 11;
this.arrow_ = Blockly.utils.createSvgElement('image',
{
'height': this.arrowSize_ + 'px',
'width': this.arrowSize_ + 'px'
});
this.arrow_.setAttributeNS('http://www.w3.org/1999/xlink',
'xlink:href', Blockly.mainWorkspace.options.pathToMedia + 'dropdown-arrow-dark.svg');
this.arrow_.style.cursor = 'pointer';
this.fieldGroup_.appendChild(this.arrow_);
this.mouseUpWrapper_ =
Blockly.bindEvent_(this.arrow_, 'mouseup', this, this.showDropdown_);
}
// Prevent the drop-down handler from changing the field colour on open.
this.disableColourChange_ = true;
};
/**
* Close the input widget if this input is being deleted.
*/
Blockly.FieldTextDropdown.prototype.dispose = function() {
if (this.mouseUpWrapper_) {
Blockly.unbindEvent_(this.mouseUpWrapper_);
this.mouseUpWrapper_ = null;
Blockly.Touch.clearTouchIdentifier();
}
Blockly.FieldTextDropdown.superClass_.dispose.call(this);
};
/**
* If the drop-down isn't open, show the text editor.
*/
Blockly.FieldTextDropdown.prototype.showEditor_ = function() {
if (!this.dropDownOpen_) {
Blockly.FieldTextDropdown.superClass_.showEditor_.call(this, null, null,
true, function() {
// When the drop-down arrow is clicked, hide text editor and show drop-down.
Blockly.WidgetDiv.hide();
this.showDropdown_();
Blockly.Touch.clearTouchIdentifier();
});
}
};
/**
* Return a list of the options for this dropdown.
* See: Blockly.FieldDropDown.prototype.getOptions_.
* @return {!Array.<!Array.<string>>} Array of option tuples:
* (human-readable text, language-neutral name).
* @private
*/
Blockly.FieldTextDropdown.prototype.getOptions_ = Blockly.FieldDropdown.prototype.getOptions_;
/**
* Position a drop-down arrow at the appropriate location at render-time.
* See: Blockly.FieldDropDown.prototype.positionArrow.
* @param {number} x X position the arrow is being rendered at, in px.
* @return {number} Amount of space the arrow is taking up, in px.
*/
Blockly.FieldTextDropdown.prototype.positionArrow = Blockly.FieldDropdown.prototype.positionArrow;
/**
* Create the dropdown menu.
* @private
*/
Blockly.FieldTextDropdown.prototype.showDropdown_ = Blockly.FieldDropdown.prototype.showEditor_;
/**
* Callback when the drop-down menu is hidden.
*/
Blockly.FieldTextDropdown.prototype.onHide = Blockly.FieldDropdown.prototype.onHide;
Blockly.Field.register('field_textdropdown', Blockly.FieldTextDropdown);