Skip to content
This repository has been archived by the owner on Dec 23, 2021. It is now read-only.

Commit

Permalink
Merge pull request #200 from microsoft/users/t-vali/microbit-template
Browse files Browse the repository at this point in the history
Microbit command opens microbit template and directs to device
  • Loading branch information
xnkevinnguyen authored Feb 12, 2020
2 parents f6c0ee3 + 3043cb9 commit 65720b2
Show file tree
Hide file tree
Showing 11 changed files with 145 additions and 47 deletions.
1 change: 1 addition & 0 deletions gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ const pythonToMove = [
"./src/*.py",
"./src/common/*.py",
"./src/requirements.txt",
"./src/templates/*.*"
];

gulp.task("python-compile", () => {
Expand Down
12 changes: 9 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
"onCommand:deviceSimulatorExpress.openSerialMonitor",
"onCommand:deviceSimulatorExpress.openSimulator",
"onCommand:deviceSimulatorExpress.runSimulator",
"onCommand:deviceSimulatorExpress.newFile",
"onCommand:deviceSimulatorExpress.newFileCPX",
"onCommand:deviceSimulatorExpress.newFileMicrobit",
"onCommand:deviceSimulatorExpress.runDevice",
"onCommand:deviceSimulatorExpress.runSimulatorEditorButton",
"onCommand:deviceSimulatorExpress.selectSerialPort",
Expand Down Expand Up @@ -85,8 +86,13 @@
}
},
{
"command": "deviceSimulatorExpress.newFile",
"title": "%deviceSimulatorExpressExtension.commands.newFile%",
"command": "deviceSimulatorExpress.newFileCPX",
"title": "%deviceSimulatorExpressExtension.commands.newFileCPX%",
"category": "%deviceSimulatorExpressExtension.commands.label%"
},
{
"command": "deviceSimulatorExpress.newFileMicrobit",
"title": "%deviceSimulatorExpressExtension.commands.newFileMicrobit%",
"category": "%deviceSimulatorExpressExtension.commands.label%"
},
{
Expand Down
4 changes: 3 additions & 1 deletion package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
"deviceSimulatorExpressExtension.commands.openSerialMonitor": "Open Serial Monitor",
"deviceSimulatorExpressExtension.commands.openSimulator": "Open Simulator",
"deviceSimulatorExpressExtension.commands.runSimulator": "Run Simulator",
"deviceSimulatorExpressExtension.commands.newFileCPX": "New Circuit Playground Express File",
"deviceSimulatorExpressExtension.commands.newFileMicrobit": "New micro:bit File",
"deviceSimulatorExpressExtension.commands.newFile": "New File",
"deviceSimulatorExpressExtension.commands.runDevice": "Deploy to Device",
"deviceSimulatorExpressExtension.commands.selectSerialPort": "Select Serial Port",
Expand All @@ -14,4 +16,4 @@
"deviceSimulatorExpressExtension.configuration.properties.device": "Whether to show 'Run Device' icon in editor title menu.",
"deviceSimulatorExpressExtension.configuration.properties.simulator": "Whether to show 'Run Simulator' icon in editor title menu.",
"deviceSimulatorExpressExtension.configuration.properties.debuggerPort": "The port the Server will listen on for communication with the debugger."
}
}
15 changes: 10 additions & 5 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,16 @@ export const CONFIG = {
};

export const CONSTANTS = {
DEVICE_NAME: {
CPX: "CPX",
MICROBIT: "micro:bit",
},
DEBUG_CONFIGURATION_TYPE: "deviceSimulatorExpress",
DEPENDENCY_CHECKER: {
PIP3: "pip3",
PYTHON: "python",
PYTHON3: "python3.7",
},
DEVICE_NAME: {
CPX: "CPX",
MICROBIT: "micro:bit",
},
ERROR: {
COMPORT_UNKNOWN_ERROR:
"Writing to COM port (GetOverlappedResult): Unknown error code 121",
Expand Down Expand Up @@ -237,6 +237,10 @@ export const CONSTANTS = {
),
},
NAME: localize("name", "Device Simulator Express"),
TEMPLATE: {
CPX: "cpx_template.py",
MICROBIT: "microbit_template.py",
},
WARNING: {
ACCEPT_AND_RUN: localize(
"warning.agreeAndRun",
Expand Down Expand Up @@ -280,7 +284,8 @@ export enum TelemetryEventName {

// Extension commands
COMMAND_DEPLOY_DEVICE = "COMMAND.DEPLOY.DEVICE",
COMMAND_NEW_FILE = "COMMAND.NEW.FILE",
COMMAND_NEW_FILE_CPX = "COMMAND.NEW.FILE.CPX",
COMMAND_NEW_FILE_MICROBIT = "COMMAND.NEW.FILE.MICROBIT",
COMMAND_OPEN_SIMULATOR = "COMMAND.OPEN.SIMULATOR",
COMMAND_RUN_SIMULATOR_BUTTON = "COMMAND.RUN.SIMULATOR_BUTTON",
COMMAND_RUN_PALETTE = "COMMAND.RUN.PALETTE",
Expand Down
57 changes: 47 additions & 10 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { SerialMonitor } from "./serialMonitor";
import { SimulatorDebugConfigurationProvider } from "./simulatorDebugConfigurationProvider";
import TelemetryAI from "./telemetry/telemetryAI";
import { UsbDetector } from "./usbDetector";
import { WEBVIEW_MESSAGES } from "./view/constants";
import { VSCODE_MESSAGES_TO_WEBVIEW, WEBVIEW_MESSAGES } from "./view/constants";

let currentFileAbsPath: string = "";
let currentTextDocument: vscode.TextDocument;
Expand Down Expand Up @@ -63,6 +63,15 @@ const setPathAndSendMessage = (
}
};

const sendCurrentDeviceMessage = (currentPanel: vscode.WebviewPanel) => {
if (currentPanel) {
currentPanel.webview.postMessage({
command: VSCODE_MESSAGES_TO_WEBVIEW.SET_DEVICE,
active_device: currentActiveDevice,
});
}
};

// Extension activation
export async function activate(context: vscode.ExtensionContext) {
console.info(CONSTANTS.INFO.EXTENSION_ACTIVATED);
Expand Down Expand Up @@ -270,6 +279,7 @@ export async function activate(context: vscode.ExtensionContext) {
context.subscriptions
);
}
sendCurrentDeviceMessage(currentPanel);
};

// Open Simulator on the webview
Expand All @@ -286,15 +296,26 @@ export async function activate(context: vscode.ExtensionContext) {
}
);

const openTemplateFile = () => {
const fileName = "template.py";
const filePath = __dirname + path.sep + fileName;
const openCPXTemplateFile = () => {
switchDevice(CONSTANTS.DEVICE_NAME.CPX);
openTemplateFile(CONSTANTS.TEMPLATE.CPX);
};

const openMicrobitTemplateFile = () => {
switchDevice(CONSTANTS.DEVICE_NAME.MICROBIT);
openTemplateFile(CONSTANTS.TEMPLATE.MICROBIT);
};

const openTemplateFile = (template: string) => {
const fileName = template;
const filePath =
__dirname + path.sep + "templates" + path.sep + fileName;
const file = fs.readFileSync(filePath, "utf8");
const showNewFilePopup: boolean = vscode.workspace
.getConfiguration()
.get(CONFIG.SHOW_NEW_FILE_POPUP);

if (showNewFilePopup) {
if (showNewFilePopup && template === CONSTANTS.TEMPLATE.CPX) {
vscode.window
.showInformationMessage(
CONSTANTS.INFO.NEW_FILE,
Expand Down Expand Up @@ -344,12 +365,27 @@ export async function activate(context: vscode.ExtensionContext) {
};
};

const newFile: vscode.Disposable = vscode.commands.registerCommand(
"deviceSimulatorExpress.newFile",
const newFileCPX: vscode.Disposable = vscode.commands.registerCommand(
"deviceSimulatorExpress.newFileCPX",
() => {
telemetryAI.trackFeatureUsage(TelemetryEventName.COMMAND_NEW_FILE);
telemetryAI.trackFeatureUsage(
TelemetryEventName.COMMAND_NEW_FILE_CPX
);
telemetryAI.runWithLatencyMeasure(
openCPXTemplateFile,
TelemetryEventName.PERFORMANCE_NEW_FILE
);
}
);

const newFileMicrobit: vscode.Disposable = vscode.commands.registerCommand(
"deviceSimulatorExpress.newFileMicrobit",
() => {
telemetryAI.trackFeatureUsage(
TelemetryEventName.COMMAND_NEW_FILE_MICROBIT
);
telemetryAI.runWithLatencyMeasure(
openTemplateFile,
openMicrobitTemplateFile,
TelemetryEventName.PERFORMANCE_NEW_FILE
);
}
Expand Down Expand Up @@ -929,7 +965,8 @@ export async function activate(context: vscode.ExtensionContext) {
installDependencies,
openSerialMonitor,
openSimulator,
newFile,
newFileCPX,
newFileMicrobit,
runSimulator,
runSimulatorEditorButton,
runDevice,
Expand Down
31 changes: 16 additions & 15 deletions src/template.py → src/templates/cpx_template.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
"""Save your file as "code.py" or "main.py" to run on the actual device.
Getting started with CPX and CircuitPython intro on:
https://learn.adafruit.com/circuitpython-made-easy-on-circuit-playground-express/circuit-playground-express-library
Find example code for CPX on:
https://github.com/adafruit/Adafruit_CircuitPython_CircuitPlayground/tree/master/examples
"""

# import CPX library
from adafruit_circuitplayground import cp

while True:
# start your code here
pass
"""
Save your file as "code.py" or "main.py" to run on the actual device.
Getting started with CPX and CircuitPython intro on:
https://learn.adafruit.com/circuitpython-made-easy-on-circuit-playground-express/circuit-playground-express-library
Find example code for CPX on:
https://github.com/adafruit/Adafruit_CircuitPython_CircuitPlayground/tree/master/examples
"""

# import CPX library
from adafruit_circuitplayground import cp

while True:
# start your code here
pass
9 changes: 9 additions & 0 deletions src/templates/microbit_template.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
"""
Get started with micro:bit and MicroPython on:
https://microbit-micropython.readthedocs.io/en/latest/.
"""

from microbit import *

while True:
display.scroll("Hello World!")
27 changes: 25 additions & 2 deletions src/view/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ import { PivotItem } from "office-ui-fabric-react";
import * as React from "react";
import "./App.css";
import { Tab } from "./components/tab/Tab";
import { DEVICE_LIST_KEY, WEBVIEW_MESSAGES } from "./constants";
import {
DEVICE_LIST_KEY,
VSCODE_MESSAGES_TO_WEBVIEW,
WEBVIEW_MESSAGES,
} from "./constants";
import { Device } from "./container/device/Device";
import { sendMessage } from "./utils/MessageUtils";

Expand All @@ -23,12 +27,21 @@ class App extends React.Component<{}, IState> {
super({});
this.state = defaultState;
}
componentDidMount() {
window.addEventListener("message", this.handleMessage);
}
componentWillUnmount() {
window.removeEventListener("message", this.handleMessage);
}

render() {
return (
<div className="App">
<main className="App-main">
<Tab handleTabClick={this.handleDeviceChange} />
<Tab
handleTabClick={this.handleDeviceChange}
currentActiveDevice={this.state.currentDevice}
/>
<Device currentSelectedDevice={this.state.currentDevice} />
</main>
</div>
Expand All @@ -43,6 +56,16 @@ class App extends React.Component<{}, IState> {
this.setState({ currentDevice: item.props.itemKey });
}
};
handleMessage = (event: any): void => {
const message = event.data;
console.log(JSON.stringify(message));
if (
message.command === VSCODE_MESSAGES_TO_WEBVIEW.SET_DEVICE &&
message.active_device !== this.state.currentDevice
) {
this.setState({ currentDevice: message.active_device });
}
};
}

export default App;
31 changes: 20 additions & 11 deletions src/view/components/cpx/Svg_utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,44 @@

// Adapted from : https://github.com/microsoft/pxt/blob/master/pxtsim/svg.ts

// tslint:disable-next-line: no-namespace
namespace svg {
export function addClass(el: SVGElement, cls: string) {
if (el.classList) el.classList.add(cls);
else if (el.className.baseVal.indexOf(cls) < 0)
if (el.classList) {
el.classList.add(cls);
} else if (el.className.baseVal.indexOf(cls) < 0) {
el.className.baseVal += " " + cls;
}
}

export function removeClass(el: SVGElement, cls: string) {
if (el.classList) el.classList.remove(cls);
else
if (el.classList) {
el.classList.remove(cls);
} else {
el.className.baseVal = el.className.baseVal
.replace(cls, "")
.replace(/\s{2,}/, " ");
}
}

export function hydrate(el: SVGElement, props: any) {
for (let k in props) {
for (const k in props) {
if (k == "title") {
svg.title(el, props[k]);
} else el.setAttributeNS(null, k, props[k]);
} else {
el.setAttributeNS(null, k, props[k]);
}
}
}

export function createElement(name: string, props?: any): SVGElement {
let newElement = document.createElementNS(
const newElement = document.createElementNS(
"http://www.w3.org/2000/svg",
name
);
if (props) svg.hydrate(newElement, props);
if (props) {
svg.hydrate(newElement, props);
}
return newElement;
}

Expand All @@ -40,7 +49,7 @@ namespace svg {
name: string,
props?: any
): SVGElement {
let childElement = svg.createElement(name, props);
const childElement = svg.createElement(name, props);
parent.appendChild(childElement);
return childElement;
}
Expand All @@ -58,13 +67,13 @@ namespace svg {
}

export function mkTitle(txt: string): SVGTitleElement {
let t = svg.createElement("title") as SVGTitleElement;
const t = svg.createElement("title") as SVGTitleElement;
t.textContent = txt;
return t;
}

export function title(el: SVGElement, txt: string): SVGTitleElement {
let t = mkTitle(txt);
const t = mkTitle(txt);
el.appendChild(t);
return t;
}
Expand Down
2 changes: 2 additions & 0 deletions src/view/components/tab/Tab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ import { CONSTANTS, DEVICE_LIST_KEY } from "../../constants";

interface IProps {
handleTabClick: (item?: PivotItem) => void;
currentActiveDevice: string;
}
export const Tab: React.FC<IProps> = props => {
return (
<Pivot
linkFormat={PivotLinkFormat.tabs}
onLinkClick={props.handleTabClick}
selectedKey={props.currentActiveDevice}
>
<PivotItem
headerText={CONSTANTS.DEVICE_NAME.CPX}
Expand Down
3 changes: 3 additions & 0 deletions src/view/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,5 +64,8 @@ export enum WEBVIEW_MESSAGES {
SENSOR_CHANGED = "sensor-changed",
SLIDER_TELEMETRY = "slider-telemetry",
}
export enum VSCODE_MESSAGES_TO_WEBVIEW {
SET_DEVICE = "set-device",
}

export default CONSTANTS;

0 comments on commit 65720b2

Please sign in to comment.