Fix angle picker: use drop-down div, Scratch-style direction (#493)

* Scratch-style FieldAngle, use DropDownDiv

* Use FieldAngle for pointindirection

* Fix FieldNumber JSON args

* Convert all math blocks to JSON

* Line length in field_angle

* Remove automatic injection of angleValidator
This commit is contained in:
Tim Mickel 2016-07-11 16:57:04 -04:00 committed by GitHub
parent c92504fd98
commit d80b588a4a
4 changed files with 80 additions and 73 deletions

View file

@ -32,32 +32,24 @@ goog.require('Blockly.Colours');
goog.require('Blockly.constants');
/**
* Common HSV hue for all blocks in this category.
*/
Blockly.Blocks.math.HUE = Blockly.Colours.textField;
Blockly.Blocks['math_number'] = {
/**
* Block for generic numeric value.
* @this Blockly.Block
*/
init: function() {
this.setHelpUrl(Blockly.Msg.MATH_NUMBER_HELPURL);
this.setColour(Blockly.Blocks.math.HUE);
this.appendDummyInput()
.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;
// Number block is trivial. Use tooltip of parent block if it exists.
this.setTooltip(function() {
var parent = thisBlock.getParent();
return (parent && parent.getInputsInline() && parent.tooltip) ||
Blockly.Msg.MATH_NUMBER_TOOLTIP;
this.jsonInit({
"message0": "%1",
"args0": [
{
"type": "field_number",
"name": "NUM"
}
],
"output": "Number",
"outputShape": Blockly.OUTPUT_SHAPE_ROUND,
"colour": Blockly.Colours.textField
});
this.setOutputShape(Blockly.OUTPUT_SHAPE_ROUND);
}
};
@ -67,12 +59,20 @@ Blockly.Blocks['math_whole_number'] = {
* @this Blockly.Block
*/
init: function() {
this.setHelpUrl(Blockly.Msg.MATH_NUMBER_HELPURL);
this.setColour(Blockly.Blocks.math.HUE);
this.appendDummyInput()
.appendField(new Blockly.FieldNumber('0', 0, Infinity, 1), 'NUM');
this.setOutput(true, 'Number');
this.setOutputShape(Blockly.OUTPUT_SHAPE_ROUND);
this.jsonInit({
"message0": "%1",
"args0": [
{
"type": "field_number",
"name": "NUM",
"min": 0,
"precision": 1
}
],
"output": "Number",
"outputShape": Blockly.OUTPUT_SHAPE_ROUND,
"colour": Blockly.Colours.textField
});
}
};
@ -82,11 +82,40 @@ Blockly.Blocks['math_positive_number'] = {
* @this Blockly.Block
*/
init: function() {
this.setHelpUrl(Blockly.Msg.MATH_NUMBER_HELPURL);
this.setColour(Blockly.Blocks.math.HUE);
this.appendDummyInput()
.appendField(new Blockly.FieldNumber('0', 0, Infinity), 'NUM');
this.setOutput(true, 'Number');
this.setOutputShape(Blockly.OUTPUT_SHAPE_ROUND);
this.jsonInit({
"message0": "%1",
"args0": [
{
"type": "field_number",
"name": "NUM",
"min": 0
}
],
"output": "Number",
"outputShape": Blockly.OUTPUT_SHAPE_ROUND,
"colour": Blockly.Colours.textField
});
}
};
Blockly.Blocks['math_angle'] = {
/**
* Block for angle picker.
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"message0": "%1",
"args0": [
{
"type": "field_angle",
"name": "NUM",
"value": 90
}
],
"output": "Number",
"outputShape": Blockly.OUTPUT_SHAPE_ROUND,
"colour": Blockly.Colours.textField
});
}
};

View file

@ -1221,8 +1221,8 @@ Blockly.Block.prototype.interpolate_ = function(message, args, lastDummyAlign) {
field = new Blockly.FieldAngle(element['angle']);
break;
case 'field_number':
field = new Blockly.FieldNumber(element['number'], null,
element['precision'], element['min'], element['max']);
field = new Blockly.FieldNumber(element['value'],
element['min'], element['max'], element['precision']);
break;
case 'field_checkbox':
field = new Blockly.FieldCheckbox(

View file

@ -26,6 +26,7 @@
goog.provide('Blockly.FieldAngle');
goog.require('Blockly.DropDownDiv');
goog.require('Blockly.FieldTextInput');
goog.require('goog.math');
goog.require('goog.userAgent');
@ -50,35 +51,6 @@ Blockly.FieldAngle = function(text, opt_validator) {
};
goog.inherits(Blockly.FieldAngle, Blockly.FieldTextInput);
/**
* Sets a new change handler for angle field.
* @param {Function} handler New change handler, or null.
*/
Blockly.FieldAngle.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.FieldAngle.angleValidator.call(this, v1);
if (v2 === undefined) {
v2 = v1;
}
}
return v2 === value ? undefined : v2;
};
} else {
wrappedHandler = Blockly.FieldAngle.angleValidator;
}
Blockly.FieldAngle.superClass_.setValidator.call(this, wrappedHandler);
};
/**
* Round angles to the nearest 15 degrees when using mouse.
* Set to 0 to disable rounding.
@ -105,19 +77,19 @@ Blockly.FieldAngle.HALF = 100 / 2;
/**
* Angle increases clockwise (true) or counterclockwise (false).
*/
Blockly.FieldAngle.CLOCKWISE = false;
Blockly.FieldAngle.CLOCKWISE = true;
/**
* Offset the location of 0 degrees (and all angles) by a constant.
* Usually either 0 (0 = right) or 90 (0 = up).
*/
Blockly.FieldAngle.OFFSET = 0;
Blockly.FieldAngle.OFFSET = 90;
/**
* Maximum allowed angle before wrapping.
* Usually either 360 (for 0 to 359.9) or 180 (for -179.9 to 180).
*/
Blockly.FieldAngle.WRAP = 360;
Blockly.FieldAngle.WRAP = 180;
/**
@ -157,11 +129,10 @@ Blockly.FieldAngle.prototype.showEditor_ = function() {
goog.userAgent.MOBILE || goog.userAgent.ANDROID || goog.userAgent.IPAD;
// Mobile browsers have issues with in-line textareas (focus & keyboards).
Blockly.FieldAngle.superClass_.showEditor_.call(this, noFocus);
var div = Blockly.WidgetDiv.DIV;
if (!div.firstChild) {
// Mobile interface uses window.prompt.
return;
}
// If there is an existing drop-down someone else owns, hide it immediately and clear it.
Blockly.DropDownDiv.hideWithoutAnimation();
Blockly.DropDownDiv.clearContent();
var div = Blockly.DropDownDiv.getContentDiv();
// Build the SVG DOM.
var svg = Blockly.createSvgElement('svg', {
'xmlns': 'http://www.w3.org/2000/svg',
@ -195,9 +166,16 @@ Blockly.FieldAngle.prototype.showEditor_ = function() {
Blockly.FieldAngle.HALF + ',' + Blockly.FieldAngle.HALF + ')'
}, svg);
}
svg.style.marginLeft = (15 - Blockly.FieldAngle.RADIUS) + 'px';
Blockly.DropDownDiv.setColour(this.sourceBlock_.parentBlock_.getColour(),
this.sourceBlock_.getColourTertiary());
Blockly.DropDownDiv.showPositionedByBlock(this, this.sourceBlock_);
this.clickWrapper_ =
Blockly.bindEvent_(svg, 'click', this, Blockly.WidgetDiv.hide);
Blockly.bindEvent_(svg, 'click', this, function() {
Blockly.WidgetDiv.hide();
Blockly.DropDownDiv.hide();
});
this.moveWrapper1_ =
Blockly.bindEvent_(circle, 'mousemove', this, this.onMouseMove);
this.moveWrapper2_ =

View file

@ -994,7 +994,7 @@
</block>
<block type="motion_pointindirection">
<value name="DIRECTION">
<shadow type="math_number">
<shadow type="math_angle">
<field name="NUM">90</field>
</shadow>
</value>