Start using field_number.

This commit is contained in:
Neil Fraser
2016-06-21 04:10:32 -07:00
parent 4b319d461d
commit 732e9b0659
7 changed files with 145 additions and 25 deletions

View File

@@ -73,7 +73,9 @@ Blockly.Blocks['controls_repeat'] = {
{
"type": "field_number",
"name": "TIMES",
"text": "10"
"value": 10,
"min": 0,
"precision": 1
}
],
"previousStatement": null,
@@ -84,8 +86,6 @@ Blockly.Blocks['controls_repeat'] = {
});
this.appendStatementInput('DO')
.appendField(Blockly.Msg.CONTROLS_REPEAT_INPUT_DO);
this.getField('TIMES').setValidator(
Blockly.FieldTextInput.nonnegativeIntegerValidator);
}
};

View File

@@ -43,8 +43,7 @@ Blockly.Blocks['math_number'] = {
this.setHelpUrl(Blockly.Msg.MATH_NUMBER_HELPURL);
this.setColour(Blockly.Blocks.math.HUE);
this.appendDummyInput()
.appendField(new Blockly.FieldNumber('0',
Blockly.FieldTextInput.numberValidator), 'NUM');
.appendField(new Blockly.FieldNumber('0'), 'NUM');
this.setOutput(true, 'Number');
// Assign 'this' to a variable for use in the tooltip closure below.
var thisBlock = this;

View File

@@ -1111,7 +1111,10 @@ Blockly.Block.prototype.interpolate_ = function(message, args, lastDummyAlign) {
element['width'], element['height'], element['alt']);
break;
case 'field_number':
field = new Blockly.FieldNumber(element['text']);
field = new Blockly.FieldNumber(element['value']);
field.setPrecision(element['precision']);
field.setMin(element['min']);
field.setMax(element['max']);
break;
case 'field_date':
if (Blockly.FieldDate) {

View File

@@ -305,16 +305,19 @@ Blockly.FieldAngle.prototype.updateGraph_ = function() {
* @return {?string} A string representing a valid angle, or null if invalid.
*/
Blockly.FieldAngle.angleValidator = function(text) {
var n = Blockly.FieldTextInput.numberValidator(text);
if (n !== null) {
n = n % 360;
if (n < 0) {
n += 360;
}
if (n > Blockly.FieldAngle.WRAP) {
n -= 360;
}
n = String(n);
if (text === null) {
return null;
}
return n;
var n = parseFloat(text || 0);
if (isNaN(n)) {
return null;
}
n = n % 360;
if (n < 0) {
n += 360;
}
if (n > Blockly.FieldAngle.WRAP) {
n -= 360;
}
return String(n);
};

View File

@@ -27,10 +27,11 @@
goog.provide('Blockly.FieldNumber');
goog.require('Blockly.FieldTextInput');
goog.require('goog.math');
/**
* Class for an editable number field.
* @param {string} text The initial content of the field.
* @param {string} value The initial content of the field.
* @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 either the accepted text, a replacement
@@ -38,8 +39,122 @@ goog.require('Blockly.FieldTextInput');
* @extends {Blockly.FieldTextInput}
* @constructor
*/
Blockly.FieldNumber = function(text, opt_validator) {
Blockly.FieldNumber.superClass_.constructor.call(this, text,
opt_validator);
Blockly.FieldNumber = function(value, opt_validator) {
Blockly.FieldNumber.superClass_.constructor.call(this, value, opt_validator);
};
goog.inherits(Blockly.FieldNumber, Blockly.FieldTextInput);
/**
* Steps between allowed numbers.
* @private
* @type {number}
*/
Blockly.FieldNumber.prototype.precision_ = 0;
/**
* Minimum allowed value.
* @private
* @type {number}
*/
Blockly.FieldNumber.prototype.min_ = -Infinity;
/**
* Maximum allowed value.
* @private
* @type {number}
*/
Blockly.FieldNumber.prototype.max_ = Infinity;
/**
* Setting precision (usually a power of 10) enforces a minimum step between
* values. That is, the user's value will rounded to the closest multiple of
* precision. The least significant digit place is inferred from the precision.
* Integers values can be enforces by choosing an integer precision.
* @param {number|string|undefined} precision Precision for value.
*/
Blockly.FieldNumber.prototype.setPrecision = function(precision) {
precision = parseFloat(precision);
if (!isNaN(precision)) {
this.precision_ = precision;
}
};
/**
* Set a maximum limit on this field's value.
* @param {number|string|undefined} max Maximum value.
*/
Blockly.FieldNumber.prototype.setMin = function(min) {
min = parseFloat(min);
if (!isNaN(min)) {
this.min_ = min;
}
};
/**
* Set a maximum limit on this field's value.
* @param {number|string|undefined} max Minimum value.
*/
Blockly.FieldNumber.prototype.setMax = function(max) {
max = parseFloat(max);
if (!isNaN(max)) {
this.max_ = max;
}
};
/**
* Sets a new change handler for number field.
* @param {Function} handler New change handler, or null.
*/
Blockly.FieldNumber.prototype.setValidator = function(handler) {
var wrappedHandler;
if (handler) {
// Wrap the user's change handler together with the angle validator.
wrappedHandler = function(value) {
var v1 = handler.call(this, value);
if (v1 === null) {
var v2 = v1;
} else {
if (v1 === undefined) {
v1 = value;
}
var v2 = Blockly.FieldNumber.numberValidator.call(this, v1);
if (v2 === undefined) {
v2 = v1;
}
}
return v2 === value ? undefined : v2;
};
} else {
wrappedHandler = Blockly.FieldNumber.numberValidator;
}
Blockly.FieldNumber.superClass_.setValidator.call(this, wrappedHandler);
};
/**
* Ensure that only a number in the correct range may be entered.
* @param {string} text The user's text.
* @return {?string} A string representing a valid number, or null if invalid.
*/
Blockly.FieldNumber.numberValidator = function(text) {
if (text === null) {
return null;
}
text = String(text);
// TODO: Handle cases like 'ten', '1.203,14', etc.
// 'O' is sometimes mistaken for '0' by inexperienced users.
text = text.replace(/O/ig, '0');
// Strip out thousands separators.
text = text.replace(/,/g, '');
var n = parseFloat(text || 0);
if (isNaN(n)) {
// Invalid number.
return null;
}
// Round to nearest multiple of precision.
if (this.precision_ && Number.isFinite(n)) {
n = Math.round(n / this.precision_) * this.precision_;
}
// Get the value in range.
n = goog.math.clamp(n, this.min_, this.max_);
return String(n);
};

View File

@@ -296,6 +296,8 @@ Blockly.FieldTextInput.prototype.widgetDispose_ = function() {
* @return {?string} A string representing a valid number, or null if invalid.
*/
Blockly.FieldTextInput.numberValidator = function(text) {
console.warn('Blockly.FieldTextInput.numberValidator is deprecated. ' +
'Use Blockly.FieldNumber instead.');
if (text === null) {
return null;
}

View File

@@ -470,11 +470,9 @@ Blockly.Blocks['field_image'] = {
.appendField(new Blockly.FieldTextInput(src), 'SRC');
this.appendDummyInput()
.appendField('width')
.appendField(new Blockly.FieldTextInput('15',
Blockly.FieldTextInput.numberValidator), 'WIDTH')
.appendField(new Blockly.FieldNumber('15'), 'WIDTH')
.appendField('height')
.appendField(new Blockly.FieldTextInput('15',
Blockly.FieldTextInput.numberValidator), 'HEIGHT')
.appendField(new Blockly.FieldNumber('15'), 'HEIGHT')
.appendField('alt text')
.appendField(new Blockly.FieldTextInput('*'), 'ALT');
this.setPreviousStatement(true, 'Field');