diff --git a/arduino-ide-extension/src/browser/arduino-commands.ts b/arduino-ide-extension/src/browser/arduino-commands.ts index 34026f34..94376fe5 100644 --- a/arduino-ide-extension/src/browser/arduino-commands.ts +++ b/arduino-ide-extension/src/browser/arduino-commands.ts @@ -6,11 +6,17 @@ export namespace ArduinoCommands { id: 'arduino-verify', label: 'Verify Sketch' } + export const VERIFY_TOOLBAR: Command = { + id: 'arduino-verify-toolbar', + } export const UPLOAD: Command = { id: 'arduino-upload', label: 'Upload Sketch' } + export const UPLOAD_TOOLBAR: Command = { + id: 'arduino-upload-toolbar', + } export const TOGGLE_COMPILE_FOR_DEBUG: Command = { id: "arduino-toggle-compile-for-debug" @@ -46,4 +52,7 @@ export namespace ArduinoCommands { export const TOGGLE_ADVANCED_MODE: Command = { id: "arduino-toggle-advanced-mode" } + export const TOGGLE_ADVANCED_MODE_TOOLBAR: Command = { + id: "arduino-toggle-advanced-mode-toolbar" + } } diff --git a/arduino-ide-extension/src/browser/arduino-frontend-contribution.tsx b/arduino-ide-extension/src/browser/arduino-frontend-contribution.tsx index 4878840f..299d4cfb 100644 --- a/arduino-ide-extension/src/browser/arduino-frontend-contribution.tsx +++ b/arduino-ide-extension/src/browser/arduino-frontend-contribution.tsx @@ -181,12 +181,12 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut registerToolbarItems(registry: TabBarToolbarRegistry): void { registry.registerItem({ id: ArduinoCommands.VERIFY.id, - command: ArduinoCommands.VERIFY.id, + command: ArduinoCommands.VERIFY_TOOLBAR.id, tooltip: 'Verify' }); registry.registerItem({ id: ArduinoCommands.UPLOAD.id, - command: ArduinoCommands.UPLOAD.id, + command: ArduinoCommands.UPLOAD_TOOLBAR.id, tooltip: 'Upload' }); registry.registerItem({ @@ -213,17 +213,15 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut }); registry.registerItem({ id: 'toggle-serial-monitor', - command: MonitorViewContribution.OPEN_SERIAL_MONITOR, - tooltip: 'Toggle Serial Monitor', - isVisible: widget => ArduinoToolbar.is(widget) && widget.side === 'right' + command: MonitorViewContribution.TOGGLE_SERIAL_MONITOR_TOOLBAR, + tooltip: 'Toggle Serial Monitor' }); registry.registerItem({ id: ArduinoCommands.TOGGLE_ADVANCED_MODE.id, - command: ArduinoCommands.TOGGLE_ADVANCED_MODE.id, + command: ArduinoCommands.TOGGLE_ADVANCED_MODE_TOOLBAR.id, tooltip: 'Toggle Advanced Mode', - text: (this.editorMode.proMode ? '$(toggle-on)' : '$(toggle-off)'), - isVisible: widget => ArduinoToolbar.is(widget) && widget.side === 'right' + text: (this.editorMode.proMode ? '$(toggle-on)' : '$(toggle-off)') }); } @@ -266,38 +264,11 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut } registry.registerCommand(ArduinoCommands.VERIFY, { + execute: this.verify.bind(this) + }); + registry.registerCommand(ArduinoCommands.VERIFY_TOOLBAR, { isVisible: widget => ArduinoToolbar.is(widget) && widget.side === 'left', - isEnabled: widget => true, - execute: async () => { - const widget = this.getCurrentWidget(); - if (widget instanceof EditorWidget) { - await widget.saveable.save(); - } - - const uri = this.toUri(widget); - if (!uri) { - return; - } - - try { - const { boardsConfig } = this.boardsServiceClient; - if (!boardsConfig || !boardsConfig.selectedBoard) { - throw new Error('No boards selected. Please select a board.'); - } - if (!boardsConfig.selectedBoard.fqbn) { - throw new Error(`No core is installed for ${boardsConfig.selectedBoard.name}. Please install the board.`); - } - // Reveal the Output view asynchronously (don't await it) - this.outputContribution.openView({ reveal: true }); - await this.coreService.compile({ - uri: uri.toString(), - board: boardsConfig.selectedBoard, - optimizeForDebug: this.editorMode.compileForDebug - }); - } catch (e) { - await this.messageService.error(e.toString()); - } - } + execute: this.verify.bind(this) }); registry.registerCommand(ArduinoCommands.TOGGLE_COMPILE_FOR_DEBUG, { @@ -309,54 +280,15 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut }); registry.registerCommand(ArduinoCommands.UPLOAD, { + execute: this.upload.bind(this) + }); + registry.registerCommand(ArduinoCommands.UPLOAD_TOOLBAR, { isVisible: widget => ArduinoToolbar.is(widget) && widget.side === 'left', - isEnabled: widget => true, - execute: async () => { - const widget = this.getCurrentWidget(); - if (widget instanceof EditorWidget) { - await widget.saveable.save(); - } - - const uri = this.toUri(widget); - if (!uri) { - return; - } - - const monitorConfig = this.monitorConnection.monitorConfig; - if (monitorConfig) { - await this.monitorConnection.disconnect(); - } - - try { - const { boardsConfig } = this.boardsServiceClient; - if (!boardsConfig || !boardsConfig.selectedBoard) { - throw new Error('No boards selected. Please select a board.'); - } - const { selectedPort } = boardsConfig; - if (!selectedPort) { - throw new Error('No ports selected. Please select a port.'); - } - // Reveal the Output view asynchronously (don't await it) - this.outputContribution.openView({ reveal: true }); - await this.coreService.upload({ - uri: uri.toString(), - board: boardsConfig.selectedBoard, - port: selectedPort.address, - optimizeForDebug: this.editorMode.compileForDebug - }); - } catch (e) { - await this.messageService.error(e.toString()); - } finally { - if (monitorConfig) { - await this.monitorConnection.connect(monitorConfig); - } - } - } + execute: this.upload.bind(this) }); registry.registerCommand(ArduinoCommands.SHOW_OPEN_CONTEXT_MENU, { isVisible: widget => ArduinoToolbar.is(widget) && widget.side === 'left', - isEnabled: widget => ArduinoToolbar.is(widget) && widget.side === 'left', execute: async (widget: Widget, target: EventTarget) => { if (this.wsSketchCount) { const el = (target as HTMLElement).parentElement; @@ -385,7 +317,6 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut }); registry.registerCommand(ArduinoCommands.SAVE_SKETCH, { - isEnabled: widget => ArduinoToolbar.is(widget) && widget.side === 'left', isVisible: widget => ArduinoToolbar.is(widget) && widget.side === 'left', execute: async (sketch: Sketch) => { registry.executeCommand(CommonCommands.SAVE_ALL.id); @@ -419,13 +350,87 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut }); registry.registerCommand(ArduinoCommands.TOGGLE_ADVANCED_MODE, { - execute: () => { - this.editorMode.toggleProMode(); - this.editorMode.menuContentChanged.fire(); - }, - isVisible: widget => ArduinoToolbar.is(widget) && widget.side === 'right', - isToggled: () => this.editorMode.proMode + isToggled: () => this.editorMode.proMode, + execute: () => this.editorMode.toggleProMode() }); + registry.registerCommand(ArduinoCommands.TOGGLE_ADVANCED_MODE_TOOLBAR, { + isVisible: widget => ArduinoToolbar.is(widget) && widget.side === 'right', + isToggled: () => this.editorMode.proMode, + execute: () => this.editorMode.toggleProMode() + }); + } + + protected async verify() { + const widget = this.getCurrentWidget(); + if (widget instanceof EditorWidget) { + await widget.saveable.save(); + } + + const uri = this.toUri(widget); + if (!uri) { + return; + } + + try { + const { boardsConfig } = this.boardsServiceClient; + if (!boardsConfig || !boardsConfig.selectedBoard) { + throw new Error('No boards selected. Please select a board.'); + } + if (!boardsConfig.selectedBoard.fqbn) { + throw new Error(`No core is installed for ${boardsConfig.selectedBoard.name}. Please install the board.`); + } + // Reveal the Output view asynchronously (don't await it) + this.outputContribution.openView({ reveal: true }); + await this.coreService.compile({ + uri: uri.toString(), + board: boardsConfig.selectedBoard, + optimizeForDebug: this.editorMode.compileForDebug + }); + } catch (e) { + await this.messageService.error(e.toString()); + } + } + + protected async upload() { + const widget = this.getCurrentWidget(); + if (widget instanceof EditorWidget) { + await widget.saveable.save(); + } + + const uri = this.toUri(widget); + if (!uri) { + return; + } + + const monitorConfig = this.monitorConnection.monitorConfig; + if (monitorConfig) { + await this.monitorConnection.disconnect(); + } + + try { + const { boardsConfig } = this.boardsServiceClient; + if (!boardsConfig || !boardsConfig.selectedBoard) { + throw new Error('No boards selected. Please select a board.'); + } + const { selectedPort } = boardsConfig; + if (!selectedPort) { + throw new Error('No ports selected. Please select a port.'); + } + // Reveal the Output view asynchronously (don't await it) + this.outputContribution.openView({ reveal: true }); + await this.coreService.upload({ + uri: uri.toString(), + board: boardsConfig.selectedBoard, + port: selectedPort.address, + optimizeForDebug: this.editorMode.compileForDebug + }); + } catch (e) { + await this.messageService.error(e.toString()); + } finally { + if (monitorConfig) { + await this.monitorConnection.connect(monitorConfig); + } + } } registerMenus(registry: MenuModelRegistry) { diff --git a/arduino-ide-extension/src/browser/editor-mode.ts b/arduino-ide-extension/src/browser/editor-mode.ts index 71125d50..c697edd4 100644 --- a/arduino-ide-extension/src/browser/editor-mode.ts +++ b/arduino-ide-extension/src/browser/editor-mode.ts @@ -1,9 +1,11 @@ import { injectable } from 'inversify'; import { Emitter } from '@theia/core/lib/common/event'; -import { ApplicationShell, FrontendApplicationContribution, FrontendApplication } from '@theia/core/lib/browser'; -import { ArduinoShellLayoutRestorer } from './shell/arduino-shell-layout-restorer'; +import { ApplicationShell, FrontendApplicationContribution, FrontendApplication, Widget } from '@theia/core/lib/browser'; import { OutputWidget } from '@theia/output/lib/browser/output-widget'; import { EditorWidget } from '@theia/editor/lib/browser'; +import { ArduinoShellLayoutRestorer } from './shell/arduino-shell-layout-restorer'; +import { BoardsListWidget } from './boards/boards-list-widget'; +import { LibraryListWidget } from './library/library-list-widget'; @injectable() export class EditorMode implements FrontendApplicationContribution { @@ -31,9 +33,9 @@ export class EditorMode implements FrontendApplicationContribution { window.localStorage.setItem(EditorMode.PRO_MODE_KEY, String(inAdvancedMode)); if (!inAdvancedMode) { const { shell } = this.app; - // Close all widget that is neither editor nor `Output`. + // Close all widgets that are neither editor nor `Output` / `Boards Manager` / `Library Manager`. for (const area of ['left', 'right', 'bottom', 'main'] as Array) { - shell.closeTabs(area, ({ owner }) => !(owner instanceof EditorWidget || owner instanceof OutputWidget)); + shell.closeTabs(area, title => !this.isInSimpleMode(title.owner)); } } // `storeLayout` has a sync API but the implementation is async, we store the layout manually before we reload the page. @@ -44,6 +46,13 @@ export class EditorMode implements FrontendApplicationContribution { window.location.reload(true); } + protected isInSimpleMode(widget: Widget): boolean { + return widget instanceof EditorWidget + || widget instanceof OutputWidget + || widget instanceof BoardsListWidget + || widget instanceof LibraryListWidget; + } + get compileForDebug(): boolean { const value = window.localStorage.getItem(EditorMode.COMPILE_FOR_DEBUG_KEY); return value === 'true'; diff --git a/arduino-ide-extension/src/browser/library/library-widget-frontend-contribution.ts b/arduino-ide-extension/src/browser/library/library-widget-frontend-contribution.ts index ed02f095..ed165c7a 100644 --- a/arduino-ide-extension/src/browser/library/library-widget-frontend-contribution.ts +++ b/arduino-ide-extension/src/browser/library/library-widget-frontend-contribution.ts @@ -27,7 +27,7 @@ export class LibraryListWidgetFrontendContribution extends AbstractViewContribut registerMenus(menus: MenuModelRegistry): void { if (this.toggleCommand) { - menus.registerMenuAction(ArduinoMenus.SKETCH, { + menus.registerMenuAction(ArduinoMenus.TOOLS, { commandId: this.toggleCommand.id, label: 'Manage Libraries...' }); diff --git a/arduino-ide-extension/src/browser/monitor/monitor-view-contribution.tsx b/arduino-ide-extension/src/browser/monitor/monitor-view-contribution.tsx index 821de29f..343cb796 100644 --- a/arduino-ide-extension/src/browser/monitor/monitor-view-contribution.tsx +++ b/arduino-ide-extension/src/browser/monitor/monitor-view-contribution.tsx @@ -5,8 +5,8 @@ import { MonitorWidget } from "./monitor-widget"; import { MenuModelRegistry, Command, CommandRegistry } from "@theia/core"; import { ArduinoMenus } from "../arduino-frontend-contribution"; import { TabBarToolbarContribution, TabBarToolbarRegistry } from "@theia/core/lib/browser/shell/tab-bar-toolbar"; -import { MonitorModel } from './monitor-model'; import { ArduinoToolbar } from '../toolbar/arduino-toolbar'; +import { MonitorModel } from './monitor-model'; export namespace SerialMonitor { export namespace Commands { @@ -29,7 +29,8 @@ export namespace SerialMonitor { @injectable() export class MonitorViewContribution extends AbstractViewContribution implements TabBarToolbarContribution { - static readonly OPEN_SERIAL_MONITOR = MonitorWidget.ID + ':toggle'; + static readonly TOGGLE_SERIAL_MONITOR = MonitorWidget.ID + ':toggle'; + static readonly TOGGLE_SERIAL_MONITOR_TOOLBAR = MonitorWidget.ID + ':toggle-toolbar'; @inject(MonitorModel) protected readonly model: MonitorModel; @@ -40,7 +41,7 @@ export class MonitorViewContribution extends AbstractViewContribution this.openView({ toggle: true, activate: true - }), - isVisible: widget => ArduinoToolbar.is(widget) && widget.side === 'right' + }) + }); + const toolbarCmd = { + id: MonitorViewContribution.TOGGLE_SERIAL_MONITOR_TOOLBAR + } + commands.registerCommand(toolbarCmd, { + isVisible: widget => ArduinoToolbar.is(widget) && widget.side === 'right', + execute: () => this.openView({ + toggle: true, + activate: true + }) }); } }