Troubleshooting updates v1.4.25 (#1012)
* sim_fix ES version update * fieldeditors-es-upgrade-to-es2017 Update es to fix issue with fieldeditors. * editor-es-upgrade-to-es2017 Update es that fixes an issue with the editor. * editor-download-dialog-fix Solving a download error that arose due to problems with the buttons in the dialog box. * return_field_motors We return the fieldmotors field, because it is necessary about the choice of types of motors: medium, large, one or two. * update-fields-for-motor-blocks Set the blocks to the fieldmotors field. Change the name of the blocks for the motors. * enable-debugger Instead of the slowmo mode, which was before, a debugger was added, in which slowmo is present. * fix-field-music It turned out to update the fieldmusic menu. The menu is now displayed in the correct position. * Update field_music.ts * fix-field-brickbutton Fixed issue with button select menu position from ev3 brick. * Update dialogs.tsx * Update field_motors.ts Repartition of Label for fieldmotos, now it's more readable, it's better. * motors-new-icon Created new icons for motors for dropdown image. * remove-ai-files-for-motors-icon Remove ai image files for motors
@ -1,4 +1,5 @@
|
||||
import * as React from "react";
|
||||
|
||||
import { canUseWebSerial, enableWebSerialAsync } from "./deploy";
|
||||
import { projectView } from "./extension";
|
||||
|
||||
@ -52,11 +53,12 @@ function explainWebSerialPairingAsync(): Promise<void> {
|
||||
|
||||
export function showUploadDialogAsync(fn: string, url: string, _confirmAsync: (options: any) => Promise<number>): Promise<void> {
|
||||
confirmAsync = _confirmAsync;
|
||||
|
||||
// https://msdn.microsoft.com/en-us/library/cc848897.aspx
|
||||
// "For security reasons, data URIs are restricted to downloaded resources.
|
||||
// Data URIs cannot be used for navigation, for scripting, or to populate frame or iframe elements"
|
||||
const downloadAgain = !pxt.BrowserUtils.isIE() && !pxt.BrowserUtils.isEdge();
|
||||
const docUrl = pxt.appTarget.appTheme.usbDocs;
|
||||
const docUrl = (pxt.appTarget.appTheme.usbDocs ? pxt.appTarget.appTheme.usbDocs : false);
|
||||
|
||||
const jsx =
|
||||
<div className="ui grid stackable">
|
||||
@ -118,7 +120,7 @@ export function showUploadDialogAsync(fn: string, url: string, _confirmAsync: (o
|
||||
hideAgree: false,
|
||||
agreeLbl: lf("I got it"),
|
||||
className: 'downloaddialog',
|
||||
buttons: [canUseWebSerial() ? {
|
||||
buttons: [canUseWebSerial() && {
|
||||
label: lf("Bluetooth"),
|
||||
icon: "bluetooth",
|
||||
className: "bluetooth focused",
|
||||
@ -127,18 +129,18 @@ export function showUploadDialogAsync(fn: string, url: string, _confirmAsync: (o
|
||||
explainWebSerialPairingAsync()
|
||||
.then(() => enableWebSerialAndCompileAsync())
|
||||
}
|
||||
} : undefined, downloadAgain ? {
|
||||
}, downloadAgain && {
|
||||
label: fn,
|
||||
icon: "download",
|
||||
className: "lightgrey focused",
|
||||
url,
|
||||
fileName: fn
|
||||
} : undefined, docUrl ? {
|
||||
}, docUrl && {
|
||||
label: lf("Help"),
|
||||
icon: "help",
|
||||
className: "lightgrey",
|
||||
url: docUrl
|
||||
} : undefined]
|
||||
}]
|
||||
//timeout: 20000
|
||||
}).then(() => { });
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"target": "es2017",
|
||||
"noImplicitAny": true,
|
||||
"noImplicitReturns": true,
|
||||
"noImplicitThis": true,
|
||||
|
@ -2,6 +2,7 @@
|
||||
/// <reference path="../node_modules/pxt-core/built/pxtsim.d.ts"/>
|
||||
|
||||
import { FieldPorts } from "./field_ports";
|
||||
import { FieldMotors } from "./field_motors";
|
||||
import { FieldBrickButtons } from "./field_brickbuttons";
|
||||
import { FieldColorEnum } from "./field_color";
|
||||
import { FieldMusic } from "./field_music";
|
||||
@ -13,6 +14,9 @@ pxt.editor.initFieldExtensionsAsync = function (opts: pxt.editor.FieldExtensionO
|
||||
fieldEditors: [{
|
||||
selector: "ports",
|
||||
editor: FieldPorts
|
||||
}, {
|
||||
selector: "motors",
|
||||
editor: FieldMotors
|
||||
}, {
|
||||
selector: "brickbuttons",
|
||||
editor: FieldBrickButtons
|
||||
|
@ -120,20 +120,17 @@ export class FieldBrickButtons extends Blockly.FieldDropdown implements Blockly.
|
||||
|
||||
Blockly.DropDownDiv.setColour('#ffffff', '#dddddd');
|
||||
|
||||
// Calculate positioning based on the field position.
|
||||
let scale = (<Blockly.WorkspaceSvg>this.sourceBlock_.workspace).scale;
|
||||
let bBox = { width: this.size_.width, height: this.size_.height };
|
||||
bBox.width *= scale;
|
||||
bBox.height *= scale;
|
||||
let position = this.fieldGroup_.getBoundingClientRect();
|
||||
let primaryX = position.left + bBox.width / 2;
|
||||
let primaryY = position.top + bBox.height;
|
||||
let secondaryX = primaryX;
|
||||
let secondaryY = position.top;
|
||||
// Set bounds to workspace; show the drop-down.
|
||||
(Blockly.DropDownDiv as any).setBoundsElement((<Blockly.WorkspaceSvg>this.sourceBlock_.workspace).getParentSvg().parentNode);
|
||||
(Blockly.DropDownDiv as any).show(this, primaryX, primaryY, secondaryX, secondaryY,
|
||||
this.onHide_.bind(this));
|
||||
// Position based on the field position.
|
||||
Blockly.DropDownDiv.showPositionedByField(this, this.onHide_.bind(this));
|
||||
|
||||
// Update colour to look selected.
|
||||
let source = this.sourceBlock_ as Blockly.BlockSvg;
|
||||
this.savedPrimary_ = source?.getColour();
|
||||
if (source?.isShadow()) {
|
||||
source.setColour(source.getColourTertiary());
|
||||
} else if (this.borderRect_) {
|
||||
this.borderRect_.setAttribute('fill', (this.sourceBlock_ as Blockly.BlockSvg).getColourTertiary());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -157,5 +154,12 @@ export class FieldBrickButtons extends Blockly.FieldDropdown implements Blockly.
|
||||
content.removeAttribute('aria-haspopup');
|
||||
content.removeAttribute('aria-activedescendant');
|
||||
(content as HTMLElement).style.width = '';
|
||||
// Update color (deselect) on dropdown hide
|
||||
let source = this.sourceBlock_ as Blockly.BlockSvg;
|
||||
if (source?.isShadow()) {
|
||||
source.setColour(this.savedPrimary_);
|
||||
} else if (this.borderRect_) {
|
||||
this.borderRect_.setAttribute('fill', this.savedPrimary_);
|
||||
}
|
||||
};
|
||||
}
|
133
fieldeditors/field_motors.ts
Normal file
@ -0,0 +1,133 @@
|
||||
/// <reference path="../node_modules/pxt-core/localtypings/blockly.d.ts"/>
|
||||
/// <reference path="../node_modules/pxt-core/built/pxtblocks.d.ts"/>
|
||||
/// <reference path="../node_modules/pxt-core/built/pxtsim.d.ts"/>
|
||||
|
||||
export interface FieldMotorsOptions extends pxtblockly.FieldImagesOptions {
|
||||
columns?: string;
|
||||
width?: string;
|
||||
//sort?: boolean;
|
||||
}
|
||||
|
||||
export class FieldMotors extends pxtblockly.FieldImages implements Blockly.FieldCustom {
|
||||
public isFieldCustom_ = true;
|
||||
//public shouldSort_: boolean;
|
||||
|
||||
constructor(text: string, options: FieldMotorsOptions, validator?: Function) {
|
||||
super(text, options, validator);
|
||||
|
||||
this.columns_ = parseInt(options.columns) || 4;
|
||||
this.width_ = parseInt(options.width) || 400;
|
||||
//this.shouldSort_ = options.sort;
|
||||
this.addLabel_ = true;
|
||||
|
||||
this.renderSelectedImage_ = Blockly.FieldDropdown.prototype.renderSelectedText_;
|
||||
this.updateSize_ = (Blockly.Field as any).prototype.updateSize_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a dropdown menu under the text.
|
||||
* @private
|
||||
*/
|
||||
public showEditor_() {
|
||||
// If there is an existing drop-down we own, this is a request to hide the drop-down.
|
||||
if (Blockly.DropDownDiv.hideIfOwner(this)) {
|
||||
return;
|
||||
}
|
||||
let sourceBlock = this.sourceBlock_ as Blockly.BlockSvg;
|
||||
// If there is an existing drop-down someone else owns, hide it immediately and clear it.
|
||||
Blockly.DropDownDiv.hideWithoutAnimation();
|
||||
Blockly.DropDownDiv.clearContent();
|
||||
// Populate the drop-down with the icons for this field.
|
||||
let dropdownDiv = Blockly.DropDownDiv.getContentDiv();
|
||||
let contentDiv = document.createElement('div');
|
||||
// Accessibility properties
|
||||
contentDiv.setAttribute('role', 'menu');
|
||||
contentDiv.setAttribute('aria-haspopup', 'true');
|
||||
const options = this.getOptions();
|
||||
//if (this.shouldSort_) options.sort();
|
||||
for (let i = 0; i < options.length; i++) {
|
||||
const content = (options[i] as any)[0]; // Human-readable text or image.
|
||||
const value = (options[i] as any)[1]; // Language-neutral value.
|
||||
// Icons with the type property placeholder take up space but don't have any functionality
|
||||
// Use for special-case layouts
|
||||
if (content.type == 'placeholder') {
|
||||
let placeholder = document.createElement('span');
|
||||
placeholder.setAttribute('class', 'blocklyDropDownPlaceholder');
|
||||
placeholder.style.width = content.width + 'px';
|
||||
placeholder.style.height = content.height + 'px';
|
||||
contentDiv.appendChild(placeholder);
|
||||
continue;
|
||||
}
|
||||
let button = document.createElement('button');
|
||||
button.setAttribute('id', ':' + i); // For aria-activedescendant
|
||||
button.setAttribute('role', 'menuitem');
|
||||
button.setAttribute('class', 'blocklyDropDownButton');
|
||||
button.title = content.alt;
|
||||
if ((this as any).columns_) {
|
||||
button.style.width = (((this as any).width_ / (this as any).columns_) - 8) + 'px';
|
||||
//button.style.height = ((this.width_ / this.columns_) - 8) + 'px';
|
||||
} else {
|
||||
button.style.width = content.width + 'px';
|
||||
button.style.height = content.height + 'px';
|
||||
}
|
||||
let backgroundColor = sourceBlock.getColour();
|
||||
if (value == this.getValue()) {
|
||||
// This icon is selected, show it in a different colour
|
||||
backgroundColor = sourceBlock.getColourTertiary();
|
||||
button.setAttribute('aria-selected', 'true');
|
||||
}
|
||||
button.style.backgroundColor = backgroundColor;
|
||||
button.style.borderColor = sourceBlock.getColourTertiary();
|
||||
Blockly.bindEvent_(button, 'click', this, this.buttonClick_);
|
||||
Blockly.bindEvent_(button, 'mouseover', button, function () {
|
||||
this.setAttribute('class', 'blocklyDropDownButton blocklyDropDownButtonHover');
|
||||
contentDiv.setAttribute('aria-activedescendant', this.id);
|
||||
});
|
||||
Blockly.bindEvent_(button, 'mouseout', button, function () {
|
||||
this.setAttribute('class', 'blocklyDropDownButton');
|
||||
contentDiv.removeAttribute('aria-activedescendant');
|
||||
});
|
||||
let buttonImg = document.createElement('img');
|
||||
buttonImg.src = content.src;
|
||||
//buttonImg.alt = icon.alt;
|
||||
// Upon click/touch, we will be able to get the clicked element as e.target
|
||||
// Store a data attribute on all possible click targets so we can match it to the icon.
|
||||
button.setAttribute('data-value', value);
|
||||
buttonImg.setAttribute('data-value', value);
|
||||
button.appendChild(buttonImg);
|
||||
if (this.addLabel_) {
|
||||
const buttonText = this.createTextNode_(content.alt);
|
||||
buttonText.setAttribute('data-value', value);
|
||||
buttonText.style.whiteSpace = 'inherit';
|
||||
buttonText.style.width = 'auto';
|
||||
buttonText.style.padding = '0 10px';
|
||||
button.appendChild(buttonText);
|
||||
}
|
||||
contentDiv.appendChild(button);
|
||||
}
|
||||
contentDiv.style.width = (this as any).width_ + 'px';
|
||||
dropdownDiv.appendChild(contentDiv);
|
||||
|
||||
Blockly.DropDownDiv.setColour(sourceBlock.getColour(), sourceBlock.getColourTertiary());
|
||||
|
||||
// Position based on the field position.
|
||||
Blockly.DropDownDiv.showPositionedByField(this, this.onHideCallback.bind(this));
|
||||
|
||||
// Update colour to look selected.
|
||||
this.savedPrimary_ = sourceBlock?.getColour();
|
||||
if (sourceBlock?.isShadow()) {
|
||||
sourceBlock.setColour(sourceBlock.style.colourTertiary);
|
||||
} else if (this.borderRect_) {
|
||||
this.borderRect_.setAttribute('fill', sourceBlock.style.colourTertiary);
|
||||
}
|
||||
}
|
||||
|
||||
trimOptions_() {
|
||||
}
|
||||
|
||||
protected buttonClick_ = function (e: any) {
|
||||
let value = e.target.getAttribute('data-value');
|
||||
this.setValue(value);
|
||||
Blockly.DropDownDiv.hide();
|
||||
};
|
||||
}
|
@ -49,7 +49,7 @@ export class FieldMusic extends pxtblockly.FieldImages implements Blockly.FieldC
|
||||
Blockly.DropDownDiv.hideWithoutAnimation();
|
||||
Blockly.DropDownDiv.clearContent();
|
||||
// Populate the drop-down with the icons for this field.
|
||||
let dropdownDiv = Blockly.DropDownDiv.getContentDiv();
|
||||
let dropdownDiv = Blockly.DropDownDiv.getContentDiv() as HTMLElement;
|
||||
let contentDiv = document.createElement('div');
|
||||
// Accessibility properties
|
||||
contentDiv.setAttribute('role', 'menu');
|
||||
@ -67,8 +67,7 @@ export class FieldMusic extends pxtblockly.FieldImages implements Blockly.FieldC
|
||||
// Accessibility properties
|
||||
categoriesDiv.setAttribute('role', 'menu');
|
||||
categoriesDiv.setAttribute('aria-haspopup', 'true');
|
||||
// FIXME: tertiary color?
|
||||
categoriesDiv.style.backgroundColor = this.sourceBlock_.getColour();
|
||||
categoriesDiv.style.backgroundColor = (this.sourceBlock_ as Blockly.BlockSvg).getColourTertiary();
|
||||
categoriesDiv.className = 'blocklyMusicFieldCategories';
|
||||
|
||||
this.refreshCategories(categoriesDiv, categories);
|
||||
@ -82,31 +81,18 @@ export class FieldMusic extends pxtblockly.FieldImages implements Blockly.FieldC
|
||||
dropdownDiv.appendChild(categoriesDiv);
|
||||
dropdownDiv.appendChild(contentDiv);
|
||||
|
||||
Blockly.DropDownDiv.setColour(this.sourceBlock_.getColour(),
|
||||
// FIXME: tertiary color?
|
||||
this.sourceBlock_.getColour());
|
||||
Blockly.DropDownDiv.setColour(this.sourceBlock_.getColour(), (this.sourceBlock_ as Blockly.BlockSvg).getColourTertiary());
|
||||
|
||||
// Calculate positioning based on the field position.
|
||||
let scale = (<Blockly.WorkspaceSvg>this.sourceBlock_.workspace).scale;
|
||||
let bBox = { width: this.size_.width, height: this.size_.height };
|
||||
bBox.width *= scale;
|
||||
bBox.height *= scale;
|
||||
let position = this.fieldGroup_.getBoundingClientRect();
|
||||
let primaryX = position.left + bBox.width / 2;
|
||||
let primaryY = position.top + bBox.height;
|
||||
let secondaryX = primaryX;
|
||||
let secondaryY = position.top;
|
||||
// Set bounds to workspace; show the drop-down.
|
||||
(Blockly.DropDownDiv as any).setBoundsElement((<Blockly.WorkspaceSvg>this.sourceBlock_.workspace).getParentSvg().parentNode);
|
||||
(Blockly.DropDownDiv as any).show(this, primaryX, primaryY, secondaryX, secondaryY,
|
||||
this.onHide_.bind(this));
|
||||
// Position based on the field position.
|
||||
Blockly.DropDownDiv.showPositionedByField(this, this.onHide_.bind(this));
|
||||
|
||||
// Update colour to look selected.
|
||||
if (this.sourceBlock_.isShadow()) {
|
||||
this.savedPrimary_ = this.sourceBlock_.getColour();
|
||||
// FIXME
|
||||
// this.sourceBlock_.setColour(this.sourceBlock_.getColourTertiary(),
|
||||
// this.sourceBlock_.getColourSecondary(), this.sourceBlock_.getColourTertiary());
|
||||
let source = this.sourceBlock_ as Blockly.BlockSvg;
|
||||
this.savedPrimary_ = source?.getColour();
|
||||
if (source?.isShadow()) {
|
||||
source.setColour(source.getColourTertiary());
|
||||
} else if (this.borderRect_) {
|
||||
this.borderRect_.setAttribute('fill', (this.sourceBlock_ as Blockly.BlockSvg).getColourTertiary());
|
||||
}
|
||||
}
|
||||
|
||||
@ -187,13 +173,11 @@ export class FieldMusic extends pxtblockly.FieldImages implements Blockly.FieldC
|
||||
let backgroundColor = this.savedPrimary_ || this.sourceBlock_.getColour();
|
||||
if (value == this.getValue()) {
|
||||
// This icon is selected, show it in a different colour
|
||||
// FIXME: tertiary color?
|
||||
backgroundColor = this.sourceBlock_.getColour();
|
||||
backgroundColor = (this.sourceBlock_ as Blockly.BlockSvg).getColourTertiary();
|
||||
button.setAttribute('aria-selected', 'true');
|
||||
}
|
||||
button.style.backgroundColor = backgroundColor;
|
||||
// FIXME: tertiary color?
|
||||
button.style.borderColor = this.sourceBlock_.getColour();
|
||||
button.style.borderColor = (this.sourceBlock_ as Blockly.BlockSvg).getColourTertiary();
|
||||
Blockly.bindEvent_(button, 'click', this, this.buttonClick_);
|
||||
Blockly.bindEvent_(button, 'mouseup', this, this.buttonClick_);
|
||||
// These are applied manually instead of using the :hover pseudoclass
|
||||
@ -241,6 +225,13 @@ export class FieldMusic extends pxtblockly.FieldImages implements Blockly.FieldC
|
||||
super.onHide_();
|
||||
(Blockly.DropDownDiv.getContentDiv() as HTMLElement).style.maxHeight = '';
|
||||
this.stopSounds();
|
||||
// Update color (deselect) on dropdown hide
|
||||
let source = this.sourceBlock_ as Blockly.BlockSvg;
|
||||
if (source?.isShadow()) {
|
||||
source.setColour(this.savedPrimary_);
|
||||
} else if (this.borderRect_) {
|
||||
this.borderRect_.setAttribute('fill', this.savedPrimary_);
|
||||
}
|
||||
}
|
||||
|
||||
protected createTextNode_(content: string) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"target": "es2017",
|
||||
"noImplicitAny": false,
|
||||
"noImplicitReturns": true,
|
||||
"module": "commonjs",
|
||||
|
BIN
libs/core/jres/icons/dualMotorLarge-portAB-icon.png
Normal file
After Width: | Height: | Size: 8.5 KiB |
BIN
libs/core/jres/icons/dualMotorLarge-portAD-icon.png
Normal file
After Width: | Height: | Size: 8.5 KiB |
BIN
libs/core/jres/icons/dualMotorLarge-portBC-icon.png
Normal file
After Width: | Height: | Size: 8.5 KiB |
BIN
libs/core/jres/icons/dualMotorLarge-portCD-icon.png
Normal file
After Width: | Height: | Size: 8.4 KiB |
BIN
libs/core/jres/icons/motorLarge-portA-icon.png
Normal file
After Width: | Height: | Size: 5.2 KiB |
BIN
libs/core/jres/icons/motorLarge-portB-icon.png
Normal file
After Width: | Height: | Size: 5.2 KiB |
BIN
libs/core/jres/icons/motorLarge-portC-icon.png
Normal file
After Width: | Height: | Size: 5.2 KiB |
BIN
libs/core/jres/icons/motorLarge-portD-icon.png
Normal file
After Width: | Height: | Size: 5.2 KiB |
BIN
libs/core/jres/icons/motorMedium-portA-icon.png
Normal file
After Width: | Height: | Size: 4.2 KiB |
BIN
libs/core/jres/icons/motorMedium-portB-icon.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
libs/core/jres/icons/motorMedium-portC-icon.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
libs/core/jres/icons/motorMedium-portD-icon.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
@ -195,7 +195,7 @@ namespace motors {
|
||||
* @param brake a value indicating if the motor should break when off
|
||||
*/
|
||||
//% blockId=outputMotorSetBrakeMode block="set %motor|brake %brake=toggleOnOff"
|
||||
//% motor.fieldEditor="speed"
|
||||
//% motor.fieldEditor="motors"
|
||||
//% motor.fieldOptions.decompileLiterals=1
|
||||
//% weight=60 blockGap=8
|
||||
//% group="Properties"
|
||||
@ -210,7 +210,7 @@ namespace motors {
|
||||
* @param value true to pause; false to continue the program execution
|
||||
*/
|
||||
//% blockId=outputMotorSetPauseMode block="set %motor|pause on run %brake=toggleOnOff"
|
||||
//% motor.fieldEditor="speed"
|
||||
//% motor.fieldEditor="motors"
|
||||
//% motor.fieldOptions.decompileLiterals=1
|
||||
//% weight=60 blockGap=8
|
||||
//% group="Properties"
|
||||
@ -223,7 +223,7 @@ namespace motors {
|
||||
* Inverts the motor polarity
|
||||
*/
|
||||
//% blockId=motorSetInverted block="set %motor|inverted %reversed=toggleOnOff"
|
||||
//% motor.fieldEditor="speed"
|
||||
//% motor.fieldEditor="motors"
|
||||
//% motor.fieldOptions.decompileLiterals=1
|
||||
//% weight=59 blockGap=8
|
||||
//% group="Properties"
|
||||
@ -241,7 +241,7 @@ namespace motors {
|
||||
* Set the settle time after braking in milliseconds (default is 10ms).
|
||||
*/
|
||||
//% blockId=motorSetBrakeSettleTime block="set %motor|brake settle time %millis|ms"
|
||||
//% motor.fieldEditor="speed"
|
||||
//% motor.fieldEditor="motors"
|
||||
//% motor.fieldOptions.decompileLiterals=1
|
||||
//% weight=1 blockGap=8
|
||||
//% group="Properties"
|
||||
@ -347,7 +347,7 @@ namespace motors {
|
||||
//% blockId=motorRun block="run %motor at %speed=motorSpeedPicker|\\%||for %value %unit"
|
||||
//% weight=100 blockGap=8
|
||||
//% group="Move"
|
||||
//% motor.fieldEditor="speed"
|
||||
//% motor.fieldEditor="motors"
|
||||
//% motor.fieldOptions.decompileLiterals=1
|
||||
//% expandableArgumentMode=toggle
|
||||
//% help=motors/motor/run
|
||||
@ -397,7 +397,7 @@ namespace motors {
|
||||
//% blockId=motorSchedule block="ramp %motor at %speed=motorSpeedPicker|\\%|for %value|%unit||accelerate %acceleration|decelerate %deceleration"
|
||||
//% weight=99 blockGap=8
|
||||
//% group="Move"
|
||||
//% motor.fieldEditor="speed"
|
||||
//% motor.fieldEditor="motors"
|
||||
//% motor.fieldOptions.decompileLiterals=1
|
||||
//% help=motors/motor/ramp
|
||||
//% inlineInputMode=inline
|
||||
@ -427,7 +427,7 @@ namespace motors {
|
||||
* of run commands.
|
||||
*/
|
||||
//% blockId=outputMotorsetRunRamp block="set %motor|run %ramp to $value||$unit"
|
||||
//% motor.fieldEditor="speed"
|
||||
//% motor.fieldEditor="motors"
|
||||
//% motor.fieldOptions.decompileLiterals=1
|
||||
//% weight=21 blockGap=8
|
||||
//% group="Properties"
|
||||
@ -499,7 +499,7 @@ namespace motors {
|
||||
* @param value true for regulated motor
|
||||
*/
|
||||
//% blockId=outputMotorSetRegulated block="set %motor|regulated %value=toggleOnOff"
|
||||
//% motor.fieldEditor="speed"
|
||||
//% motor.fieldEditor="motors"
|
||||
//% motor.fieldOptions.decompileLiterals=1
|
||||
//% weight=58 blockGap=8
|
||||
//% group="Properties"
|
||||
@ -525,7 +525,7 @@ namespace motors {
|
||||
* @param timeOut optional maximum pausing time in milliseconds
|
||||
*/
|
||||
//% blockId=motorPauseUntilRead block="pause until %motor|ready"
|
||||
//% motor.fieldEditor="speed"
|
||||
//% motor.fieldEditor="motors"
|
||||
//% motor.fieldOptions.decompileLiterals=1
|
||||
//% weight=90 blockGap=8
|
||||
//% group="Move"
|
||||
@ -584,7 +584,7 @@ namespace motors {
|
||||
* @param motor the port which connects to the motor
|
||||
*/
|
||||
//% blockId=motorSpeed block="%motor|speed"
|
||||
//% motor.fieldEditor="speed"
|
||||
//% motor.fieldEditor="motors"
|
||||
//% motor.fieldOptions.decompileLiterals=1
|
||||
//% weight=72
|
||||
//% blockGap=8
|
||||
@ -600,7 +600,7 @@ namespace motors {
|
||||
* @param motor the port which connects to the motor
|
||||
*/
|
||||
//% blockId=motorAngle block="%motor|angle"
|
||||
//% motor.fieldEditor="speed"
|
||||
//% motor.fieldEditor="motors"
|
||||
//% motor.fieldOptions.decompileLiterals=1
|
||||
//% weight=70
|
||||
//% blockGap=8
|
||||
@ -615,7 +615,7 @@ namespace motors {
|
||||
* Clears the motor count
|
||||
*/
|
||||
//% blockId=motorClearCount block="clear %motor|counters"
|
||||
//% motor.fieldEditor="speed"
|
||||
//% motor.fieldEditor="motors"
|
||||
//% motor.fieldOptions.decompileLiterals=1
|
||||
//% weight=68
|
||||
//% blockGap=8
|
||||
@ -644,7 +644,7 @@ namespace motors {
|
||||
* Pauses the program until the motor is stalled.
|
||||
*/
|
||||
//% blockId=motorPauseUntilStall block="pause until %motor|stalled"
|
||||
//% motor.fieldEditor="speed"
|
||||
//% motor.fieldEditor="motors"
|
||||
//% motor.fieldOptions.decompileLiterals=1
|
||||
//% weight=89
|
||||
//% group="Move"
|
||||
@ -669,28 +669,28 @@ namespace motors {
|
||||
}
|
||||
}
|
||||
|
||||
//% whenUsed fixedInstance block="large motor A" jres=icons.portA
|
||||
//% whenUsed fixedInstance block="large motor A" jres=icons.motorLargePortA
|
||||
export const largeA = new Motor(Output.A, true);
|
||||
|
||||
//% whenUsed fixedInstance block="large motor B" jres=icons.portB
|
||||
//% whenUsed fixedInstance block="large motor B" jres=icons.motorLargePortB
|
||||
export const largeB = new Motor(Output.B, true);
|
||||
|
||||
//% whenUsed fixedInstance block="large motor C" jres=icons.portC
|
||||
//% whenUsed fixedInstance block="large motor C" jres=icons.motorLargePortC
|
||||
export const largeC = new Motor(Output.C, true);
|
||||
|
||||
//% whenUsed fixedInstance block="large motor D" jres=icons.portD
|
||||
//% whenUsed fixedInstance block="large motor D" jres=icons.motorLargePortD
|
||||
export const largeD = new Motor(Output.D, true);
|
||||
|
||||
//% whenUsed fixedInstance block="medium motor A" jres=icons.portA
|
||||
//% whenUsed fixedInstance block="medium motor A" jres=icons.motorMeduimPortA
|
||||
export const mediumA = new Motor(Output.A, false);
|
||||
|
||||
//% whenUsed fixedInstance block="medium motor B" jres=icons.portB
|
||||
//% whenUsed fixedInstance block="medium motor B" jres=icons.motorMeduimPortB
|
||||
export const mediumB = new Motor(Output.B, false);
|
||||
|
||||
//% whenUsed fixedInstance block="medium motor C" jres=icons.portC
|
||||
//% whenUsed fixedInstance block="medium motor C" jres=icons.motorMeduimPortC
|
||||
export const mediumC = new Motor(Output.C, false);
|
||||
|
||||
//% whenUsed fixedInstance block="medium motor D" jres=icons.portD
|
||||
//% whenUsed fixedInstance block="medium motor D" jres=icons.motorMeduimPortD
|
||||
export const mediumD = new Motor(Output.D, false);
|
||||
|
||||
//% fixedInstances
|
||||
@ -721,7 +721,7 @@ namespace motors {
|
||||
* @param unit (optional) unit of the value
|
||||
*/
|
||||
//% blockId=motorPairTank block="tank **motors** %motors %speedLeft=motorSpeedPicker|\\% %speedRight=motorSpeedPicker|\\%||for %value %unit"
|
||||
//% motors.fieldEditor="ports"
|
||||
//% motors.fieldEditor="motors"
|
||||
//% weight=96 blockGap=8
|
||||
//% inlineInputMode=inline
|
||||
//% group="Move"
|
||||
@ -751,7 +751,7 @@ namespace motors {
|
||||
* @param unit (optional) unit of the value
|
||||
*/
|
||||
//% blockId=motorPairSteer block="steer **motors** %chassis turn ratio %turnRatio=motorTurnRatioPicker speed %speed=motorSpeedPicker|\\%||for %value %unit"
|
||||
//% chassis.fieldEditor="ports"
|
||||
//% chassis.fieldEditor="motors"
|
||||
//% weight=95
|
||||
//% turnRatio.min=-200 turnRatio=200
|
||||
//% inlineInputMode=inline
|
||||
@ -824,16 +824,16 @@ namespace motors {
|
||||
}
|
||||
}
|
||||
|
||||
//% whenUsed fixedInstance block="B+C" jres=icons.portBC
|
||||
//% whenUsed fixedInstance block="large motors B+C" jres=icons.dualMotorLargePortBC
|
||||
export const largeBC = new SynchedMotorPair(Output.BC);
|
||||
|
||||
//% whenUsed fixedInstance block="A+D" jres=icons.portAD
|
||||
//% whenUsed fixedInstance block="large motors A+D" jres=icons.dualMotorLargePortAD
|
||||
export const largeAD = new SynchedMotorPair(Output.AD);
|
||||
|
||||
//% whenUsed fixedInstance block="A+B" jres=icons.portAB
|
||||
//% whenUsed fixedInstance block="large motors A+B" jres=icons.dualMotorLargePortAB
|
||||
export const largeAB = new SynchedMotorPair(Output.AB);
|
||||
|
||||
//% whenUsed fixedInstance block="C+D" jres=icons.portCD
|
||||
//% whenUsed fixedInstance block="large motors C+D" jres=icons.dualMotorLargePortCD
|
||||
export const largeCD = new SynchedMotorPair(Output.CD);
|
||||
|
||||
function reset(out: Output) {
|
||||
|
@ -159,6 +159,7 @@
|
||||
"extendEditor": true,
|
||||
"extendFieldEditors": true,
|
||||
"scriptManager": true,
|
||||
"debugger": true,
|
||||
"importExtensionFiles": true,
|
||||
"experiments": [
|
||||
"python",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"target": "es2017",
|
||||
"noImplicitAny": true,
|
||||
"noImplicitReturns": true,
|
||||
"declaration": true,
|
||||
@ -8,7 +8,7 @@
|
||||
"rootDir": ".",
|
||||
"newLine": "LF",
|
||||
"sourceMap": false,
|
||||
"lib": ["dom", "dom.iterable", "scripthost", "es6"],
|
||||
"lib": ["dom", "dom.iterable", "scripthost", "es2017"],
|
||||
"types": [],
|
||||
"typeRoots": ["../node_modules/@types"]
|
||||
}
|
||||
|