2018-01-04 01:18:39 +01:00
|
|
|
/// <reference path="../node_modules/pxt-core/built/pxteditor.d.ts"/>
|
|
|
|
/// <reference path="../node_modules/pxt-core/built/pxtsim.d.ts"/>
|
|
|
|
|
|
|
|
import { deployCoreAsync, initAsync } from "./deploy";
|
|
|
|
import { FieldPorts } from "./field_ports";
|
2018-01-04 02:20:35 +01:00
|
|
|
import { FieldImages } from "./field_images";
|
2018-01-10 07:05:26 +01:00
|
|
|
import { FieldSpeed } from "./field_speed";
|
2018-01-07 16:52:07 +01:00
|
|
|
import { FieldBrickButtons } from "./field_brickbuttons";
|
2018-01-10 07:05:26 +01:00
|
|
|
import { FieldTurnRatio } from "./field_turnratio";
|
2018-01-04 01:18:39 +01:00
|
|
|
|
2018-01-30 00:21:15 +01:00
|
|
|
pxt.editor.initExtensionsAsync = function (opts: pxt.editor.ExtensionOptions): Promise<pxt.editor.ExtensionResult> {
|
2018-01-04 01:18:39 +01:00
|
|
|
pxt.debug('loading pxt-ev3 target extensions...')
|
|
|
|
updateBlocklyShape();
|
|
|
|
const res: pxt.editor.ExtensionResult = {
|
|
|
|
fieldEditors: [{
|
|
|
|
selector: "ports",
|
|
|
|
editor: FieldPorts
|
2018-01-04 02:20:35 +01:00
|
|
|
}, {
|
|
|
|
selector: "images",
|
|
|
|
editor: FieldImages
|
2018-01-06 23:25:50 +01:00
|
|
|
}, {
|
|
|
|
selector: "speed",
|
|
|
|
editor: FieldSpeed
|
2018-01-07 16:52:07 +01:00
|
|
|
}, {
|
|
|
|
selector: "brickbuttons",
|
|
|
|
editor: FieldBrickButtons
|
2018-01-10 07:05:26 +01:00
|
|
|
}, {
|
|
|
|
selector: "turnratio",
|
|
|
|
editor: FieldTurnRatio
|
2018-01-04 01:18:39 +01:00
|
|
|
}],
|
2018-01-30 00:21:15 +01:00
|
|
|
deployCoreAsync,
|
|
|
|
showUploadInstructionsAsync: (fn: string, url: string, confirmAsync: (options: any) => Promise<number>) => {
|
|
|
|
let resolve: (thenableOrResult?: void | PromiseLike<void>) => void;
|
|
|
|
let reject: (error: any) => void;
|
|
|
|
const deferred = new Promise<void>((res, rej) => {
|
|
|
|
resolve = res;
|
|
|
|
reject = rej;
|
|
|
|
});
|
|
|
|
const boardName = pxt.appTarget.appTheme.boardName || "???";
|
|
|
|
const boardDriveName = pxt.appTarget.appTheme.driveDisplayName || pxt.appTarget.compile.driveName || "???";
|
|
|
|
|
|
|
|
// 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 saveAs = pxt.BrowserUtils.hasSaveAs();
|
|
|
|
|
|
|
|
const htmlBody = `
|
|
|
|
<div class="ui three column grid stackable">
|
|
|
|
<div class="column">
|
|
|
|
<div class="ui">
|
|
|
|
<div class="image">
|
|
|
|
<img class="ui medium rounded image" src="./static/download/connect.svg" style="height:109px;width:261px;margin-bottom:1rem;">
|
|
|
|
</div>
|
|
|
|
<div class="content">
|
|
|
|
<div class="description">
|
|
|
|
<span class="ui yellow circular label">1</span>
|
|
|
|
<strong>${lf("Connect EV3 to computer with USB cable")}</strong>
|
|
|
|
<br/>
|
|
|
|
${lf("Use the miniUSB port on top of EV3 brick")}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="column">
|
|
|
|
<div class="ui">
|
|
|
|
<div class="image">
|
|
|
|
<img class="ui medium rounded image" src="./static/download/firmware.svg" style="height:109px;width:261px;margin-bottom:1rem;">
|
|
|
|
</div>
|
|
|
|
<div class="content">
|
|
|
|
<div class="description">
|
|
|
|
<span class="ui blue circular label">2</span>
|
|
|
|
<strong>${lf("Make sure you have the latest EV3 firmware")}</strong>
|
|
|
|
<br/>
|
2018-02-14 18:36:20 +01:00
|
|
|
<a href="https://ev3manager.education.lego.com/" target="_blank">${lf("Click here to update to latest firmware")}</a>
|
2018-01-30 00:21:15 +01:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="column">
|
|
|
|
<div class="ui">
|
|
|
|
<div class="image">
|
|
|
|
<img class="ui medium rounded image" src="./static/download/transfer.svg" style="height:109px;width:261px;margin-bottom:1rem;">
|
|
|
|
</div>
|
|
|
|
<div class="content">
|
|
|
|
<div class="description">
|
|
|
|
<span class="ui blue circular label">3</span>
|
|
|
|
${lf("Move the .uf2 file to EV3 brick")}
|
|
|
|
<br/>
|
|
|
|
${lf("Locate the downloaded .uf2 file and drag it to the EV3 drive")}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>`;
|
|
|
|
|
|
|
|
return confirmAsync({
|
|
|
|
header: lf("Download to your EV3"),
|
|
|
|
htmlBody,
|
|
|
|
hasCloseIcon: true,
|
|
|
|
hideCancel: true,
|
|
|
|
hideAgree: false,
|
|
|
|
agreeLbl: lf("I got it"),
|
|
|
|
buttons: [downloadAgain ? {
|
|
|
|
label: fn,
|
|
|
|
icon: "download",
|
|
|
|
class: "lightgrey focused",
|
|
|
|
url,
|
|
|
|
fileName: fn
|
|
|
|
} : undefined, docUrl ? {
|
|
|
|
label: lf("Help"),
|
|
|
|
icon: "help",
|
|
|
|
class: "lightgrey",
|
|
|
|
url: docUrl
|
|
|
|
} : undefined]
|
|
|
|
//timeout: 20000
|
|
|
|
}).then(() => { });
|
|
|
|
}
|
2018-01-04 01:18:39 +01:00
|
|
|
};
|
|
|
|
initAsync().catch(e => {
|
|
|
|
// probably no HID - we'll try this again upon deployment
|
|
|
|
})
|
|
|
|
return Promise.resolve<pxt.editor.ExtensionResult>(res);
|
2017-07-06 18:34:31 +02:00
|
|
|
}
|
2017-07-25 12:48:02 +02:00
|
|
|
|
2018-01-04 01:18:39 +01:00
|
|
|
/**
|
|
|
|
* Update the shape of Blockly blocks with square corners
|
|
|
|
*/
|
|
|
|
function updateBlocklyShape() {
|
2017-07-06 18:34:31 +02:00
|
|
|
|
2018-01-02 22:32:07 +01:00
|
|
|
/**
|
2018-01-04 01:18:39 +01:00
|
|
|
* Rounded corner radius.
|
|
|
|
* @const
|
2018-01-02 22:32:07 +01:00
|
|
|
*/
|
2018-01-04 01:18:39 +01:00
|
|
|
(Blockly.BlockSvg as any).CORNER_RADIUS = 0 * (Blockly.BlockSvg as any).GRID_UNIT;
|
2018-01-02 22:32:07 +01:00
|
|
|
|
2018-01-04 01:18:39 +01:00
|
|
|
/**
|
|
|
|
* Inner space between edge of statement input and notch.
|
|
|
|
* @const
|
|
|
|
*/
|
|
|
|
(Blockly.BlockSvg as any).STATEMENT_INPUT_INNER_SPACE = 3 * (Blockly.BlockSvg as any).GRID_UNIT;
|
|
|
|
/**
|
|
|
|
* SVG path for drawing next/previous notch from left to right.
|
|
|
|
* @const
|
|
|
|
*/
|
|
|
|
(Blockly.BlockSvg as any).NOTCH_PATH_LEFT = (
|
|
|
|
'l 8,8 ' +
|
|
|
|
'h 16 ' +
|
|
|
|
'l 8,-8 '
|
|
|
|
);
|
2018-01-02 22:32:07 +01:00
|
|
|
|
2018-01-04 01:18:39 +01:00
|
|
|
/**
|
|
|
|
* SVG path for drawing next/previous notch from right to left.
|
|
|
|
* @const
|
|
|
|
*/
|
|
|
|
(Blockly.BlockSvg as any).NOTCH_PATH_RIGHT = (
|
|
|
|
'l -8,8 ' +
|
|
|
|
'h -16 ' +
|
|
|
|
'l -8,-8 '
|
|
|
|
);
|
2018-01-02 22:32:07 +01:00
|
|
|
|
2018-01-04 01:18:39 +01:00
|
|
|
/**
|
|
|
|
* SVG start point for drawing the top-left corner.
|
|
|
|
* @const
|
|
|
|
*/
|
|
|
|
(Blockly.BlockSvg as any).TOP_LEFT_CORNER_START =
|
|
|
|
'm 0,' + 0;
|
2018-01-02 22:32:07 +01:00
|
|
|
|
2018-01-04 01:18:39 +01:00
|
|
|
/**
|
|
|
|
* SVG path for drawing the rounded top-left corner.
|
|
|
|
* @const
|
|
|
|
*/
|
|
|
|
(Blockly.BlockSvg as any).TOP_LEFT_CORNER =
|
|
|
|
'l ' + (Blockly.BlockSvg as any).CORNER_RADIUS + ',0 ';
|
2018-01-02 22:32:07 +01:00
|
|
|
|
2018-01-04 01:18:39 +01:00
|
|
|
/**
|
|
|
|
* SVG path for drawing the rounded top-right corner.
|
|
|
|
* @const
|
|
|
|
*/
|
|
|
|
(Blockly.BlockSvg as any).TOP_RIGHT_CORNER =
|
|
|
|
'l ' + 0 + ',' + (Blockly.BlockSvg as any).CORNER_RADIUS;
|
2018-01-02 22:32:07 +01:00
|
|
|
|
2018-01-04 01:18:39 +01:00
|
|
|
/**
|
|
|
|
* SVG path for drawing the rounded bottom-right corner.
|
|
|
|
* @const
|
|
|
|
*/
|
|
|
|
(Blockly.BlockSvg as any).BOTTOM_RIGHT_CORNER =
|
|
|
|
'l 0,' + (Blockly.BlockSvg as any).CORNER_RADIUS;
|
2018-01-02 22:32:07 +01:00
|
|
|
|
2018-01-04 01:18:39 +01:00
|
|
|
/**
|
|
|
|
* SVG path for drawing the rounded bottom-left corner.
|
|
|
|
* @const
|
|
|
|
*/
|
|
|
|
(Blockly.BlockSvg as any).BOTTOM_LEFT_CORNER =
|
|
|
|
'l -' + (Blockly.BlockSvg as any).CORNER_RADIUS + ',0';
|
2018-01-02 22:32:07 +01:00
|
|
|
|
2018-01-04 01:18:39 +01:00
|
|
|
/**
|
|
|
|
* SVG path for drawing the top-left corner of a statement input.
|
|
|
|
* @const
|
|
|
|
*/
|
|
|
|
(Blockly.BlockSvg as any).INNER_TOP_LEFT_CORNER =
|
|
|
|
'l ' + (Blockly.BlockSvg as any).CORNER_RADIUS + ',-' + 0;
|
2018-01-02 22:32:07 +01:00
|
|
|
|
2018-01-04 01:18:39 +01:00
|
|
|
/**
|
|
|
|
* SVG path for drawing the bottom-left corner of a statement input.
|
|
|
|
* Includes the rounded inside corner.
|
|
|
|
* @const
|
|
|
|
*/
|
|
|
|
(Blockly.BlockSvg as any).INNER_BOTTOM_LEFT_CORNER =
|
|
|
|
'l ' + 0 + ',' + (Blockly.BlockSvg as any).CORNER_RADIUS * 2 +
|
|
|
|
'l ' + (Blockly.BlockSvg as any).CORNER_RADIUS + ',' + 0;
|
2018-01-02 22:32:07 +01:00
|
|
|
|
2018-01-06 02:35:25 +01:00
|
|
|
/**
|
|
|
|
* Corner radius of the flyout background.
|
|
|
|
* @type {number}
|
|
|
|
* @const
|
|
|
|
*/
|
|
|
|
(Blockly as any).Flyout.prototype.CORNER_RADIUS = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Margin around the edges of the blocks in the flyout.
|
|
|
|
* @type {number}
|
|
|
|
* @const
|
|
|
|
*/
|
|
|
|
(Blockly as any).Flyout.prototype.MARGIN = 8;
|
|
|
|
|
2017-07-06 18:58:15 +02:00
|
|
|
}
|
2018-01-04 01:18:39 +01:00
|
|
|
|
|
|
|
// When require()d from node, bind the global pxt namespace
|
|
|
|
// namespace pxt {
|
|
|
|
// export const dummyExport = 1;
|
|
|
|
// }
|
|
|
|
// eval("if (typeof process === 'object' && process + '' === '[object process]') pxt = global.pxt")
|