mirror of
https://github.com/scratchfoundation/scratch-blocks.git
synced 2025-08-28 22:10:31 -04:00
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:
parent
c92504fd98
commit
d80b588a4a
4 changed files with 80 additions and 73 deletions
|
@ -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
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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_ =
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue