From 04ee4b2f4576f6f08fabab9a83952d1e407ecc74 Mon Sep 17 00:00:00 2001 From: Luke Slevinsky Date: Mon, 19 Aug 2019 13:07:18 -0700 Subject: [PATCH 1/6] Get backend working for select file to play --- src/extension.ts | 58 ++++++++++++++++++-------- src/extension_utils/utils.ts | 68 +++++++++++++++++++++---------- src/view/components/Dropdown.tsx | 57 ++++++++++++++++++++++++++ src/view/components/Simulator.tsx | 48 +++++++++++++++++++--- src/view/constants.ts | 3 +- 5 files changed, 190 insertions(+), 44 deletions(-) create mode 100644 src/view/components/Dropdown.tsx diff --git a/src/extension.ts b/src/extension.ts index 50673951c..4dcbc6fe1 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -40,6 +40,14 @@ function loadScript(context: vscode.ExtensionContext, scriptPath: string) { .toString()}">`; } +const setPathAndSendMessage = (currentPanel: vscode.WebviewPanel, newFilePath: string) => { + currentFileAbsPath = newFilePath; + currentPanel.webview.postMessage({ + command: "current-file", + state: { chosen_editor: newFilePath } + }); +} + // Extension activation export async function activate(context: vscode.ExtensionContext) { console.info(CONSTANTS.INFO.EXTENSION_ACTIVATED); @@ -48,6 +56,7 @@ export async function activate(context: vscode.ExtensionContext) { let currentPanel: vscode.WebviewPanel | undefined; let childProcess: cp.ChildProcess | undefined; let messageListener: vscode.Disposable; + let activeEditorListener: vscode.Disposable; // Add our library path to settings.json for autocomplete functionality updatePythonExtraPaths(); @@ -66,7 +75,7 @@ export async function activate(context: vscode.ExtensionContext) { } vscode.workspace.onDidSaveTextDocument(async (document: vscode.TextDocument) => { - await updateCurrentFileIfPython(document); + await updateCurrentFileIfPython(document, currentPanel); }); const openWebview = () => { @@ -76,7 +85,7 @@ export async function activate(context: vscode.ExtensionContext) { currentPanel = vscode.window.createWebviewPanel( "adafruitSimulator", CONSTANTS.LABEL.WEBVIEW_PANEL, - { preserveFocus: true, viewColumn: vscode.ViewColumn.Two }, + { preserveFocus: true, viewColumn: vscode.ViewColumn.Beside }, { // Only allow the webview to access resources in our extension's media directory localResourceRoots: [ @@ -96,6 +105,14 @@ export async function activate(context: vscode.ExtensionContext) { } } + if (activeEditorListener !== undefined) { + activeEditorListener.dispose(); + const index = context.subscriptions.indexOf(activeEditorListener); + if (index > -1) { + context.subscriptions.splice(index, 1); + } + } + if (currentPanel) { // Handle messages from webview messageListener = currentPanel.webview.onDidReceiveMessage( @@ -114,7 +131,11 @@ export async function activate(context: vscode.ExtensionContext) { break; case WebviewMessages.PLAY_SIMULATOR: console.log(`Play button ${messageJson} \n`); - if (message.text as boolean) { + if (message.text.state as boolean) { + currentFileAbsPath = message.text.chosen_editor + if (currentFileAbsPath) { + currentTextDocument = utils.getActiveEditorFromPath(currentFileAbsPath); + } telemetryAI.trackFeatureUsage(TelemetryEventName.COMMAND_RUN_SIMULATOR_BUTTON); runSimulatorCommand(); } else { @@ -143,6 +164,8 @@ export async function activate(context: vscode.ExtensionContext) { undefined, context.subscriptions ); + + activeEditorListener = utils.addVisibleTextEditorCallback(currentPanel, context); } currentPanel.onDidDispose( @@ -292,7 +315,7 @@ export async function activate(context: vscode.ExtensionContext) { killProcessIfRunning(); - await updateCurrentFileIfPython(vscode.window.activeTextEditor!.document); + await updateCurrentFileIfPython(vscode.window.activeTextEditor!.document, currentPanel); if (currentFileAbsPath === "") { utils.logToOutputChannel(outChannel, CONSTANTS.ERROR.NO_FILE_TO_RUN, true); @@ -425,7 +448,7 @@ export async function activate(context: vscode.ExtensionContext) { utils.logToOutputChannel(outChannel, CONSTANTS.INFO.DEPLOY_DEVICE); - await updateCurrentFileIfPython(vscode.window.activeTextEditor!.document); + await updateCurrentFileIfPython(vscode.window.activeTextEditor!.document, currentPanel); if (currentFileAbsPath === "") { utils.logToOutputChannel(outChannel, CONSTANTS.ERROR.NO_FILE_TO_RUN, true); @@ -570,13 +593,13 @@ export async function activate(context: vscode.ExtensionContext) { UsbDetector.getInstance().initialize(context.extensionPath); UsbDetector.getInstance().startListening(); - if (CPXWorkspace.rootPath && + if (CPXWorkspace.rootPath && (utils.fileExistsSync(path.join(CPXWorkspace.rootPath, CPX_CONFIG_FILE)) || vscode.window.activeTextEditor)) { - (() => { - if (!SerialMonitor.getInstance().initialized) { - SerialMonitor.getInstance().initialize(); - } - })(); + (() => { + if (!SerialMonitor.getInstance().initialized) { + SerialMonitor.getInstance().initialize(); + } + })(); } // Debugger configuration @@ -660,16 +683,17 @@ const getFileFromFilePicker = () => { }; const updateCurrentFileIfPython = async ( - activeTextDocument: vscode.TextDocument | undefined + activeTextDocument: vscode.TextDocument | undefined, + currentPanel: vscode.WebviewPanel ) => { if (activeTextDocument && activeTextDocument.languageId === "python") { - currentFileAbsPath = activeTextDocument.fileName; + setPathAndSendMessage(currentPanel, activeTextDocument.fileName); currentTextDocument = activeTextDocument; } else if (currentFileAbsPath === "") { - currentFileAbsPath = - getActivePythonFile() || (await getFileFromFilePicker()) || ""; + setPathAndSendMessage(currentPanel, + getActivePythonFile() || (await getFileFromFilePicker()) || ""); } - if (currentFileAbsPath) { + if (utils.getActiveEditorFromPath(activeTextDocument.fileName) === undefined) { await vscode.window.showTextDocument(currentTextDocument, vscode.ViewColumn.One); } }; @@ -725,6 +749,6 @@ function getWebviewContent(context: vscode.ExtensionContext) { export async function deactivate() { const monitor: SerialMonitor = SerialMonitor.getInstance(); - await monitor.closeSerialMonitor(null, false); + await monitor.closeSerialMonitor(null, false); UsbDetector.getInstance().stopListening(); } diff --git a/src/extension_utils/utils.ts b/src/extension_utils/utils.ts index 9df7a6434..b1b1515f9 100644 --- a/src/extension_utils/utils.ts +++ b/src/extension_utils/utils.ts @@ -5,16 +5,16 @@ import * as fs from "fs"; import * as path from "path"; import { DependencyChecker } from "./dependencyChecker"; import { DeviceContext } from "../deviceContext"; -import { ExtensionContext, MessageItem, OutputChannel, Uri, window } from "vscode"; +import * as vscode from "vscode"; import { CONSTANTS, CPX_CONFIG_FILE, DialogResponses, USER_CODE_NAMES } from "../constants"; // tslint:disable-next-line: export-name export const getPathToScript = ( - context: ExtensionContext, + context: vscode.ExtensionContext, folderName: string, fileName: string ) => { - const onDiskPath = Uri.file( + const onDiskPath = vscode.Uri.file( path.join(context.extensionPath, folderName, fileName) ); const scriptPath = onDiskPath.with({ scheme: "vscode-resource" }); @@ -29,12 +29,12 @@ export const validCodeFileName = (filePath: string) => { }; export const showPrivacyModal = (okAction: () => void) => { - window.showInformationMessage( + vscode.window.showInformationMessage( `${CONSTANTS.INFO.THIRD_PARTY_WEBSITE}: ${CONSTANTS.LINKS.PRIVACY}`, DialogResponses.AGREE_AND_PROCEED, DialogResponses.CANCEL, ) - .then((privacySelection: MessageItem | undefined) => { + .then((privacySelection: vscode.MessageItem | undefined) => { if (privacySelection === DialogResponses.AGREE_AND_PROCEED) { okAction(); } else if (privacySelection === DialogResponses.CANCEL) { @@ -44,7 +44,7 @@ export const showPrivacyModal = (okAction: () => void) => { } export const logToOutputChannel = ( - outChannel: OutputChannel | undefined, + outChannel: vscode.OutputChannel | undefined, message: string, show: boolean = false ): void => { @@ -60,7 +60,7 @@ export function tryParseJSON(jsonString: string): any | boolean { try { const jsonObj = JSON.parse(jsonString); if (jsonObj && typeof jsonObj === "object") { - return jsonObj; + return jsonObj; } } catch (exception) { } @@ -105,23 +105,23 @@ export function directoryExistsSync(dirPath: string): boolean { */ export function padStart(sourceString: string, targetLength: number, padString?: string): string { if (!sourceString) { - return sourceString; + return sourceString; } if (!(String.prototype as any).padStart) { - // https://github.com/uxitten/polyfill/blob/master/string.polyfill.js - padString = String(padString || " "); - if (sourceString.length > targetLength) { - return sourceString; - } else { - targetLength = targetLength - sourceString.length; - if (targetLength > padString.length) { - padString += padString.repeat(targetLength / padString.length); // append to original to ensure we are longer than needed - } - return padString.slice(0, targetLength) + sourceString; + // https://github.com/uxitten/polyfill/blob/master/string.polyfill.js + padString = String(padString || " "); + if (sourceString.length > targetLength) { + return sourceString; + } else { + targetLength = targetLength - sourceString.length; + if (targetLength > padString.length) { + padString += padString.repeat(targetLength / padString.length); // append to original to ensure we are longer than needed } + return padString.slice(0, targetLength) + sourceString; + } } else { - return (sourceString as any).padStart(targetLength, padString); + return (sourceString as any).padStart(targetLength, padString); } } @@ -151,9 +151,9 @@ export const setPythonExectuableName = async () => { if (dependencyCheck.installed) { executableName = dependencyCheck.dependency; } else { - window.showErrorMessage(CONSTANTS.ERROR.NO_PYTHON_PATH, + vscode.window.showErrorMessage(CONSTANTS.ERROR.NO_PYTHON_PATH, DialogResponses.INSTALL_PYTHON) - .then((selection: MessageItem | undefined) => { + .then((selection: vscode.MessageItem | undefined) => { if (selection === DialogResponses.INSTALL_PYTHON) { const okAction = () => { open(CONSTANTS.LINKS.DOWNLOAD_PYTHON); @@ -165,3 +165,29 @@ export const setPythonExectuableName = async () => { return executableName; } + +export const addVisibleTextEditorCallback = (currentPanel: vscode.WebviewPanel, context: vscode.ExtensionContext): vscode.Disposable => { + const initialPythonEditors = filterForPythonFiles(vscode.window.visibleTextEditors); + currentPanel.webview.postMessage({ + command: "visible-editors", + state: { activePythonEditors: initialPythonEditors } + }); + return vscode.window.onDidChangeVisibleTextEditors((textEditors: vscode.TextEditor[]) => { + const activePythonEditors = filterForPythonFiles(textEditors); + console.log("python", textEditors[0].document.fileName, activePythonEditors); + currentPanel.webview.postMessage({ + command: "visible-editors", + state: { activePythonEditors } + }); + }, {}, context.subscriptions) +} + +export const filterForPythonFiles = (textEditors: vscode.TextEditor[]) => { + return textEditors.filter( + editor => editor.document.languageId === "python" + ).map(editor => editor.document.fileName); +} + +export const getActiveEditorFromPath = (filePath: string): vscode.TextDocument => { + return vscode.window.visibleTextEditors.find((editor: vscode.TextEditor) => editor.document.fileName === filePath).document +} diff --git a/src/view/components/Dropdown.tsx b/src/view/components/Dropdown.tsx new file mode 100644 index 000000000..f321a9e7a --- /dev/null +++ b/src/view/components/Dropdown.tsx @@ -0,0 +1,57 @@ +import * as React from "react"; +import "../styles/Button.css"; + +export interface IDropdownProps { + label: string; + textOptions: string[]; + lastChosen: string; + styleLabel: string; + width: number; + onBlur: (event: React.FocusEvent) => void; +} + +const Dropdown: React.FC = props => { + const defaultText = + props.lastChosen !== "" + ? `${parsePath(props.lastChosen)[1]}: ${parsePath(props.lastChosen)[0]}` + : "Choose a .py file to run on the Simulator"; + return ( +
+ +
+ ); +}; + +const renderOptions = (options: string[]) => { + return options.map((name, index) => { + const key = `option-${index}`; + const filePath = parsePath(name); + return ( + + ); + }); +}; + +const parsePath = (filePath: string) => { + const lastSlash = + filePath.lastIndexOf("/") !== -1 + ? filePath.lastIndexOf("/") + : filePath.lastIndexOf("\\"); + return [filePath.slice(0, lastSlash), filePath.substr(lastSlash + 1)]; +}; + +const styleDropdownOptions = (classA:string, classB:string, pathToParse:string) => { + const parsedPath = parsePath(pathToParse); + return ( +

{parsedPath[1]}

{parsedPath[0]}

+ ); +}; + +export default Dropdown; diff --git a/src/view/components/Simulator.tsx b/src/view/components/Simulator.tsx index 2c1df1245..ca83c2e1a 100644 --- a/src/view/components/Simulator.tsx +++ b/src/view/components/Simulator.tsx @@ -5,6 +5,7 @@ import * as React from "react"; import { BUTTON_NEUTRAL, BUTTON_PRESSED } from "./cpx/Cpx_svg_style"; import Cpx, { updateSwitch, updatePinTouch } from "./cpx/Cpx"; import Button from "./Button"; +import Dropdown from "./Dropdown"; import { CONSTANTS } from "../constants"; import PlayLogo from "../svgs/play_svg"; import StopLogo from "../svgs/stop_svg"; @@ -23,6 +24,8 @@ interface ICpxState { } interface IState { + active_editors: string[]; + chosen_editor: string; cpx: ICpxState; play_button: boolean; } @@ -51,8 +54,6 @@ const DEFAULT_CPX_STATE: ICpxState = { touch: [false, false, false, false, false, false, false] }; -const SIMULATOR_BUTTON_WIDTH = 60; - interface vscode { postMessage(message: any): void; } @@ -67,6 +68,8 @@ class Simulator extends React.Component { constructor(props: IMyProps) { super(props); this.state = { + active_editors: [], + chosen_editor: "", cpx: DEFAULT_CPX_STATE, play_button: false }; @@ -78,6 +81,7 @@ class Simulator extends React.Component { this.onMouseLeave = this.onMouseLeave.bind(this); this.togglePlayClick = this.togglePlayClick.bind(this); this.refreshSimulatorClick = this.refreshSimulatorClick.bind(this); + this.onSelectBlur = this.onSelectBlur.bind(this); } handleMessage = (event: any): void => { @@ -98,6 +102,25 @@ class Simulator extends React.Component { case "activate-play": this.setState({ ...this.state, play_button: !this.state.play_button }); break; + case "visible-editors": + console.log( + "Setting active editors", + message.state.activePythonEditors + ); + if (message.state.activePythonEditors.length > 0) { + this.setState({ + ...this.state, + active_editors: message.state.activePythonEditors + }); + } + break; + case "current-file": + console.log("Setting current file", message.state.chosen_editor); + this.setState({ + ...this.state, + chosen_editor: message.state.chosen_editor + }); + break; default: console.log("Invalid message received from the extension."); this.setState({ ...this.state, cpx: DEFAULT_CPX_STATE }); @@ -120,6 +143,14 @@ class Simulator extends React.Component { return (
+ { image={image} styleLabel="play" label="play" - width={SIMULATOR_BUTTON_WIDTH} + width={CONSTANTS.SIMULATOR_BUTTON_WIDTH} />
@@ -155,7 +186,10 @@ class Simulator extends React.Component { } protected togglePlayClick() { - sendMessage("play-simulator", !this.state.play_button); + sendMessage("play-simulator", { + chosen_editor: this.state.chosen_editor, + state: !this.state.play_button + }); const button = window.document.getElementById(CONSTANTS.ID_NAME.PLAY_BUTTON) || window.document.getElementById(CONSTANTS.ID_NAME.STOP_BUTTON); @@ -174,6 +208,10 @@ class Simulator extends React.Component { } } + protected onSelectBlur(event: React.FocusEvent) { + console.log("BLURR", event.currentTarget.value); + this.setState({ ...this.state, chosen_editor: event.currentTarget.value }); + } protected onKeyEvent(event: KeyboardEvent, active: boolean) { let element; const target = event.target as SVGElement; diff --git a/src/view/constants.ts b/src/view/constants.ts index 449911863..b454ea92b 100644 --- a/src/view/constants.ts +++ b/src/view/constants.ts @@ -41,7 +41,8 @@ export const CONSTANTS = { "https://learn.adafruit.com/adafruit-circuit-playground-express/circuitpython-quickstart", PRIVACY: "https://www.adafruit.com/privacy" }, - TOOLBAR_INFO: `Explore what's on the board:` + SIMULATOR_BUTTON_WIDTH: 60, + TOOLBAR_INFO: `Explore what's on the board:`, }; export default CONSTANTS; From 4e9ddc95eb7bc8ace5364408d7c0c4c3fcd78aec Mon Sep 17 00:00:00 2001 From: Luke Slevinsky Date: Mon, 19 Aug 2019 13:07:40 -0700 Subject: [PATCH 2/6] Make dropdown work and look better --- package.json | 2 +- src/extension.ts | 41 ++++++++++++++----------------- src/extension_utils/utils.ts | 3 ++- src/view/components/Dropdown.tsx | 24 +++++++++--------- src/view/components/Simulator.tsx | 32 +++++++++++++----------- src/view/constants.ts | 1 + src/view/styles/Dropdown.css | 31 +++++++++++++++++++++++ src/view/styles/Simulator.css | 4 +++ 8 files changed, 85 insertions(+), 53 deletions(-) create mode 100644 src/view/styles/Dropdown.css diff --git a/package.json b/package.json index 373699ddf..c9df16921 100644 --- a/package.json +++ b/package.json @@ -262,7 +262,6 @@ "css-loader": "^1.0.0", "del": "^4.0.0", "event-stream": "^4.0.1", - "glob": "^7.1.4", "gulp": "^4.0.2", "gulp-cli": "^2.1.0", "gulp-filter": "^5.1.0", @@ -294,6 +293,7 @@ "compare-versions": "^3.5.1", "eventemitter2": "^5.0.1", "open": "^6.4.0", + "glob": "^7.1.4", "os": "^0.1.1", "react": "^16.8.6", "react-dom": "^16.8.6", diff --git a/src/extension.ts b/src/extension.ts index 4dcbc6fe1..145b9206b 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -44,7 +44,7 @@ const setPathAndSendMessage = (currentPanel: vscode.WebviewPanel, newFilePath: s currentFileAbsPath = newFilePath; currentPanel.webview.postMessage({ command: "current-file", - state: { chosen_editor: newFilePath } + state: { running_file: newFilePath } }); } @@ -132,9 +132,12 @@ export async function activate(context: vscode.ExtensionContext) { case WebviewMessages.PLAY_SIMULATOR: console.log(`Play button ${messageJson} \n`); if (message.text.state as boolean) { - currentFileAbsPath = message.text.chosen_editor + setPathAndSendMessage(currentPanel, message.text.selected_file); if (currentFileAbsPath) { - currentTextDocument = utils.getActiveEditorFromPath(currentFileAbsPath); + const foundDocument = utils.getActiveEditorFromPath(currentFileAbsPath); + if (foundDocument !== undefined) { + currentTextDocument = foundDocument; + } } telemetryAI.trackFeatureUsage(TelemetryEventName.COMMAND_RUN_SIMULATOR_BUTTON); runSimulatorCommand(); @@ -319,6 +322,11 @@ export async function activate(context: vscode.ExtensionContext) { if (currentFileAbsPath === "") { utils.logToOutputChannel(outChannel, CONSTANTS.ERROR.NO_FILE_TO_RUN, true); + vscode.window + .showErrorMessage( + CONSTANTS.ERROR.NO_FILE_TO_RUN, + DialogResponses.MESSAGE_UNDERSTOOD + ) } else { // Save on run await currentTextDocument.save(); @@ -452,6 +460,11 @@ export async function activate(context: vscode.ExtensionContext) { if (currentFileAbsPath === "") { utils.logToOutputChannel(outChannel, CONSTANTS.ERROR.NO_FILE_TO_RUN, true); + vscode.window + .showErrorMessage( + CONSTANTS.ERROR.NO_FILE_TO_RUN, + DialogResponses.MESSAGE_UNDERSTOOD + ); } else if (!utils.validCodeFileName(currentFileAbsPath)) { // Save on run await currentTextDocument.save(); @@ -664,24 +677,6 @@ const getActivePythonFile = () => { return activeEditor ? activeEditor.document.fileName : ""; }; -const getFileFromFilePicker = () => { - const options: vscode.OpenDialogOptions = { - canSelectMany: false, - filters: { - "All files": ["*"], - "Python files": ["py"] - }, - openLabel: "Run File" - }; - - return vscode.window.showOpenDialog(options).then(fileUri => { - if (fileUri && fileUri[0] && fileUri[0].fsPath.endsWith(".py")) { - console.log(`Selected file: ${fileUri[0].fsPath}`); - return fileUri[0].fsPath; - } - }); -}; - const updateCurrentFileIfPython = async ( activeTextDocument: vscode.TextDocument | undefined, currentPanel: vscode.WebviewPanel @@ -691,9 +686,9 @@ const updateCurrentFileIfPython = async ( currentTextDocument = activeTextDocument; } else if (currentFileAbsPath === "") { setPathAndSendMessage(currentPanel, - getActivePythonFile() || (await getFileFromFilePicker()) || ""); + getActivePythonFile() || ""); } - if (utils.getActiveEditorFromPath(activeTextDocument.fileName) === undefined) { + if (utils.getActiveEditorFromPath(currentTextDocument.fileName) === undefined) { await vscode.window.showTextDocument(currentTextDocument, vscode.ViewColumn.One); } }; diff --git a/src/extension_utils/utils.ts b/src/extension_utils/utils.ts index b1b1515f9..0ce6c3a3f 100644 --- a/src/extension_utils/utils.ts +++ b/src/extension_utils/utils.ts @@ -189,5 +189,6 @@ export const filterForPythonFiles = (textEditors: vscode.TextEditor[]) => { } export const getActiveEditorFromPath = (filePath: string): vscode.TextDocument => { - return vscode.window.visibleTextEditors.find((editor: vscode.TextEditor) => editor.document.fileName === filePath).document + const activeEditor = vscode.window.visibleTextEditors.find((editor: vscode.TextEditor) => editor.document.fileName === filePath); + return activeEditor ? activeEditor.document : undefined; } diff --git a/src/view/components/Dropdown.tsx b/src/view/components/Dropdown.tsx index f321a9e7a..2d8ce589b 100644 --- a/src/view/components/Dropdown.tsx +++ b/src/view/components/Dropdown.tsx @@ -1,5 +1,9 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + import * as React from "react"; -import "../styles/Button.css"; +import CONSTANTS from "../constants"; +import "../styles/Dropdown.css"; export interface IDropdownProps { label: string; @@ -11,13 +15,14 @@ export interface IDropdownProps { } const Dropdown: React.FC = props => { + const parsedPath = parsePath(props.lastChosen); const defaultText = props.lastChosen !== "" - ? `${parsePath(props.lastChosen)[1]}: ${parsePath(props.lastChosen)[0]}` - : "Choose a .py file to run on the Simulator"; + ? `${parsedPath[1]} : ${parsedPath[0]}` + : CONSTANTS.NO_FILES_AVAILABLE; return (
- @@ -30,10 +35,10 @@ const Dropdown: React.FC = props => { const renderOptions = (options: string[]) => { return options.map((name, index) => { const key = `option-${index}`; - const filePath = parsePath(name); + const parsedPath = parsePath(name); return ( ); }); @@ -47,11 +52,4 @@ const parsePath = (filePath: string) => { return [filePath.slice(0, lastSlash), filePath.substr(lastSlash + 1)]; }; -const styleDropdownOptions = (classA:string, classB:string, pathToParse:string) => { - const parsedPath = parsePath(pathToParse); - return ( -

{parsedPath[1]}

{parsedPath[0]}

- ); -}; - export default Dropdown; diff --git a/src/view/components/Simulator.tsx b/src/view/components/Simulator.tsx index ca83c2e1a..6461d4927 100644 --- a/src/view/components/Simulator.tsx +++ b/src/view/components/Simulator.tsx @@ -25,7 +25,8 @@ interface ICpxState { interface IState { active_editors: string[]; - chosen_editor: string; + running_file: string; + selected_file: string; cpx: ICpxState; play_button: boolean; } @@ -69,9 +70,10 @@ class Simulator extends React.Component { super(props); this.state = { active_editors: [], - chosen_editor: "", cpx: DEFAULT_CPX_STATE, - play_button: false + play_button: false, + running_file: "", + selected_file: "" }; this.handleClick = this.handleClick.bind(this); @@ -107,18 +109,16 @@ class Simulator extends React.Component { "Setting active editors", message.state.activePythonEditors ); - if (message.state.activePythonEditors.length > 0) { - this.setState({ - ...this.state, - active_editors: message.state.activePythonEditors - }); - } + this.setState({ + ...this.state, + active_editors: message.state.activePythonEditors + }); break; case "current-file": - console.log("Setting current file", message.state.chosen_editor); + console.log("Setting current file", message.state.running_file); this.setState({ ...this.state, - chosen_editor: message.state.chosen_editor + running_file: message.state.running_file }); break; default: @@ -142,15 +142,17 @@ class Simulator extends React.Component { const image = this.state.play_button ? StopLogo : PlayLogo; return (
-
+
+
+
{ protected togglePlayClick() { sendMessage("play-simulator", { - chosen_editor: this.state.chosen_editor, + selected_file: this.state.selected_file, state: !this.state.play_button }); const button = @@ -210,7 +212,7 @@ class Simulator extends React.Component { protected onSelectBlur(event: React.FocusEvent) { console.log("BLURR", event.currentTarget.value); - this.setState({ ...this.state, chosen_editor: event.currentTarget.value }); + this.setState({ ...this.state, selected_file: event.currentTarget.value }); } protected onKeyEvent(event: KeyboardEvent, active: boolean) { let element; diff --git a/src/view/constants.ts b/src/view/constants.ts index b454ea92b..9676198fe 100644 --- a/src/view/constants.ts +++ b/src/view/constants.ts @@ -34,6 +34,7 @@ export const CONSTANTS = { NUMERIC_SIX: "Digit6", NUMERIC_SEVEN: "Digit7" }, + NO_FILES_AVAILABLE: "Choose a .py file to run on the Simulator", REDIRECT: { DESCRIPTION: 'By clicking "Agree and Proceed" you will be redirected to adafruit.com, a third party website not managed by Microsoft. Please note that your activity on adafruit.com is subject to Adafruit\'s privacy policy', diff --git a/src/view/styles/Dropdown.css b/src/view/styles/Dropdown.css new file mode 100644 index 000000000..5eda3f9b8 --- /dev/null +++ b/src/view/styles/Dropdown.css @@ -0,0 +1,31 @@ +.dropdown { + background: var(--vscode-debugToolBar-background); + border: var(--vscode-debugToolBar-background); + border-radius: 2px; + max-width: 300px; + min-width: 240px; + box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.22); + color: var(--vscode-foreground); + height: 32px; + padding-left: 8px; + padding-right: 4px; +} + +select.dropdown:hover, +select.dropdown:focus, +select.dropdown:active { + outline: 1px solid var(--vscode-button-background); + outline-offset: 1px; +} + +option:disabled { + background: grey; +} + +option { + height: 32px; + background: var(--vscode-debugToolBar-background); + align-items: center; + font-size: 14px; + color: white; +} diff --git a/src/view/styles/Simulator.css b/src/view/styles/Simulator.css index 0106b9a63..404ddc9e7 100644 --- a/src/view/styles/Simulator.css +++ b/src/view/styles/Simulator.css @@ -10,3 +10,7 @@ padding: 20px; justify-content: center; } + +.file-selector { + padding: 20px; +} From b7db65cb453e4380fda72f805a9529944f4517e4 Mon Sep 17 00:00:00 2001 From: Luke Slevinsky Date: Mon, 19 Aug 2019 13:16:18 -0700 Subject: [PATCH 3/6] make dropdown work for high contrast --- package.json | 9 +++++++++ src/view/styles/Dropdown.css | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index c9df16921..a54289e19 100644 --- a/package.json +++ b/package.json @@ -95,6 +95,15 @@ } ], "colors": [ + { + "id": "highContrastButtonBorderOverride.color", + "description": "Color for the high contrast border updated", + "defaults": { + "dark": "debugToolBar.background", + "light": "debugToolBar.background", + "highContrast": "#6FC3DF" + } + }, { "id": "badgeForegroundOverwrite", "description": "Color that fixes the issue with midnight blue ", diff --git a/src/view/styles/Dropdown.css b/src/view/styles/Dropdown.css index 5eda3f9b8..564236b6a 100644 --- a/src/view/styles/Dropdown.css +++ b/src/view/styles/Dropdown.css @@ -1,6 +1,6 @@ .dropdown { background: var(--vscode-debugToolBar-background); - border: var(--vscode-debugToolBar-background); + border-color: var(--vscode-highContrastButtonBorderOverride-color); border-radius: 2px; max-width: 300px; min-width: 240px; From baa13773263a306074bd9146253ef9e694428097 Mon Sep 17 00:00:00 2001 From: Luke Slevinsky Date: Mon, 19 Aug 2019 17:08:52 -0700 Subject: [PATCH 4/6] Fix some UI from review --- src/extension.ts | 3 ++- src/view/components/Dropdown.tsx | 2 +- src/view/styles/Dropdown.css | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 400ae116d..160962563 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -80,7 +80,7 @@ export async function activate(context: vscode.ExtensionContext) { const openWebview = () => { if (currentPanel) { - currentPanel.reveal(vscode.ViewColumn.Two); + currentPanel.reveal(vscode.ViewColumn.Beside); } else { currentPanel = vscode.window.createWebviewPanel( "adafruitSimulator", @@ -169,6 +169,7 @@ export async function activate(context: vscode.ExtensionContext) { ); activeEditorListener = utils.addVisibleTextEditorCallback(currentPanel, context); + console.log("sent"); } currentPanel.onDidDispose( diff --git a/src/view/components/Dropdown.tsx b/src/view/components/Dropdown.tsx index 2d8ce589b..e74292f52 100644 --- a/src/view/components/Dropdown.tsx +++ b/src/view/components/Dropdown.tsx @@ -18,7 +18,7 @@ const Dropdown: React.FC = props => { const parsedPath = parsePath(props.lastChosen); const defaultText = props.lastChosen !== "" - ? `${parsedPath[1]} : ${parsedPath[0]}` + ? `Currently running: ${parsedPath[1]}` : CONSTANTS.NO_FILES_AVAILABLE; return (
diff --git a/src/view/styles/Dropdown.css b/src/view/styles/Dropdown.css index 564236b6a..036f007e8 100644 --- a/src/view/styles/Dropdown.css +++ b/src/view/styles/Dropdown.css @@ -19,7 +19,7 @@ select.dropdown:active { } option:disabled { - background: grey; + background: var(--vscode-editor-selectionHighlightBackground); } option { @@ -27,5 +27,5 @@ option { background: var(--vscode-debugToolBar-background); align-items: center; font-size: 14px; - color: white; + color: var(--vscode-foreground); } From 2e011f49175584b4825a6d81990356549ed97169 Mon Sep 17 00:00:00 2001 From: Luke Slevinsky Date: Mon, 19 Aug 2019 17:11:16 -0700 Subject: [PATCH 5/6] remove log statement --- src/extension_utils/utils.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/extension_utils/utils.ts b/src/extension_utils/utils.ts index 0ce6c3a3f..332d90bf5 100644 --- a/src/extension_utils/utils.ts +++ b/src/extension_utils/utils.ts @@ -174,7 +174,6 @@ export const addVisibleTextEditorCallback = (currentPanel: vscode.WebviewPanel, }); return vscode.window.onDidChangeVisibleTextEditors((textEditors: vscode.TextEditor[]) => { const activePythonEditors = filterForPythonFiles(textEditors); - console.log("python", textEditors[0].document.fileName, activePythonEditors); currentPanel.webview.postMessage({ command: "visible-editors", state: { activePythonEditors } From 8af73c28201a665bc777a2b822ede4dbb984e995 Mon Sep 17 00:00:00 2001 From: Luke Slevinsky Date: Mon, 19 Aug 2019 19:04:27 -0700 Subject: [PATCH 6/6] Address comments --- src/view/components/Dropdown.tsx | 10 +++++++--- src/view/components/Simulator.tsx | 5 ++--- src/view/constants.ts | 3 +++ src/view/styles/Dropdown.css | 4 ---- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/view/components/Dropdown.tsx b/src/view/components/Dropdown.tsx index e74292f52..d84c09cf3 100644 --- a/src/view/components/Dropdown.tsx +++ b/src/view/components/Dropdown.tsx @@ -2,7 +2,7 @@ // Licensed under the MIT license. import * as React from "react"; -import CONSTANTS from "../constants"; +import { CONSTANTS } from "../constants"; import "../styles/Dropdown.css"; export interface IDropdownProps { @@ -18,11 +18,15 @@ const Dropdown: React.FC = props => { const parsedPath = parsePath(props.lastChosen); const defaultText = props.lastChosen !== "" - ? `Currently running: ${parsedPath[1]}` + ? CONSTANTS.CURRENTLY_RUNNING(parsedPath[1]) : CONSTANTS.NO_FILES_AVAILABLE; return (
- diff --git a/src/view/components/Simulator.tsx b/src/view/components/Simulator.tsx index 6461d4927..1986db75e 100644 --- a/src/view/components/Simulator.tsx +++ b/src/view/components/Simulator.tsx @@ -144,8 +144,8 @@ class Simulator extends React.Component {
{ } protected onSelectBlur(event: React.FocusEvent) { - console.log("BLURR", event.currentTarget.value); this.setState({ ...this.state, selected_file: event.currentTarget.value }); } protected onKeyEvent(event: KeyboardEvent, active: boolean) { diff --git a/src/view/constants.ts b/src/view/constants.ts index 9676198fe..34a9b476d 100644 --- a/src/view/constants.ts +++ b/src/view/constants.ts @@ -3,6 +3,9 @@ // Key events export const CONSTANTS = { + CURRENTLY_RUNNING: (file: string) => { + return `Currently running: ${file}` + }, ID_NAME: { BUTTON_A: "BTN_A_OUTER", BUTTON_AB: "BTN_AB_OUTER", diff --git a/src/view/styles/Dropdown.css b/src/view/styles/Dropdown.css index 036f007e8..c1b355d26 100644 --- a/src/view/styles/Dropdown.css +++ b/src/view/styles/Dropdown.css @@ -18,10 +18,6 @@ select.dropdown:active { outline-offset: 1px; } -option:disabled { - background: var(--vscode-editor-selectionHighlightBackground); -} - option { height: 32px; background: var(--vscode-debugToolBar-background);