Fixed: Commands that are registered to toolbar did not show up in Electron menu

This commit is contained in:
Miro Spönemann 2020-02-26 10:55:03 +01:00
parent 69c7383da8
commit d56962251e
5 changed files with 132 additions and 99 deletions

View File

@ -6,11 +6,17 @@ export namespace ArduinoCommands {
id: 'arduino-verify', id: 'arduino-verify',
label: 'Verify Sketch' label: 'Verify Sketch'
} }
export const VERIFY_TOOLBAR: Command = {
id: 'arduino-verify-toolbar',
}
export const UPLOAD: Command = { export const UPLOAD: Command = {
id: 'arduino-upload', id: 'arduino-upload',
label: 'Upload Sketch' label: 'Upload Sketch'
} }
export const UPLOAD_TOOLBAR: Command = {
id: 'arduino-upload-toolbar',
}
export const TOGGLE_COMPILE_FOR_DEBUG: Command = { export const TOGGLE_COMPILE_FOR_DEBUG: Command = {
id: "arduino-toggle-compile-for-debug" id: "arduino-toggle-compile-for-debug"
@ -46,4 +52,7 @@ export namespace ArduinoCommands {
export const TOGGLE_ADVANCED_MODE: Command = { export const TOGGLE_ADVANCED_MODE: Command = {
id: "arduino-toggle-advanced-mode" id: "arduino-toggle-advanced-mode"
} }
export const TOGGLE_ADVANCED_MODE_TOOLBAR: Command = {
id: "arduino-toggle-advanced-mode-toolbar"
}
} }

View File

@ -181,12 +181,12 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut
registerToolbarItems(registry: TabBarToolbarRegistry): void { registerToolbarItems(registry: TabBarToolbarRegistry): void {
registry.registerItem({ registry.registerItem({
id: ArduinoCommands.VERIFY.id, id: ArduinoCommands.VERIFY.id,
command: ArduinoCommands.VERIFY.id, command: ArduinoCommands.VERIFY_TOOLBAR.id,
tooltip: 'Verify' tooltip: 'Verify'
}); });
registry.registerItem({ registry.registerItem({
id: ArduinoCommands.UPLOAD.id, id: ArduinoCommands.UPLOAD.id,
command: ArduinoCommands.UPLOAD.id, command: ArduinoCommands.UPLOAD_TOOLBAR.id,
tooltip: 'Upload' tooltip: 'Upload'
}); });
registry.registerItem({ registry.registerItem({
@ -213,17 +213,15 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut
}); });
registry.registerItem({ registry.registerItem({
id: 'toggle-serial-monitor', id: 'toggle-serial-monitor',
command: MonitorViewContribution.OPEN_SERIAL_MONITOR, command: MonitorViewContribution.TOGGLE_SERIAL_MONITOR_TOOLBAR,
tooltip: 'Toggle Serial Monitor', tooltip: 'Toggle Serial Monitor'
isVisible: widget => ArduinoToolbar.is(widget) && widget.side === 'right'
}); });
registry.registerItem({ registry.registerItem({
id: ArduinoCommands.TOGGLE_ADVANCED_MODE.id, id: ArduinoCommands.TOGGLE_ADVANCED_MODE.id,
command: ArduinoCommands.TOGGLE_ADVANCED_MODE.id, command: ArduinoCommands.TOGGLE_ADVANCED_MODE_TOOLBAR.id,
tooltip: 'Toggle Advanced Mode', tooltip: 'Toggle Advanced Mode',
text: (this.editorMode.proMode ? '$(toggle-on)' : '$(toggle-off)'), text: (this.editorMode.proMode ? '$(toggle-on)' : '$(toggle-off)')
isVisible: widget => ArduinoToolbar.is(widget) && widget.side === 'right'
}); });
} }
@ -266,38 +264,11 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut
} }
registry.registerCommand(ArduinoCommands.VERIFY, { registry.registerCommand(ArduinoCommands.VERIFY, {
execute: this.verify.bind(this)
});
registry.registerCommand(ArduinoCommands.VERIFY_TOOLBAR, {
isVisible: widget => ArduinoToolbar.is(widget) && widget.side === 'left', isVisible: widget => ArduinoToolbar.is(widget) && widget.side === 'left',
isEnabled: widget => true, execute: this.verify.bind(this)
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());
}
}
}); });
registry.registerCommand(ArduinoCommands.TOGGLE_COMPILE_FOR_DEBUG, { registry.registerCommand(ArduinoCommands.TOGGLE_COMPILE_FOR_DEBUG, {
@ -309,54 +280,15 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut
}); });
registry.registerCommand(ArduinoCommands.UPLOAD, { registry.registerCommand(ArduinoCommands.UPLOAD, {
execute: this.upload.bind(this)
});
registry.registerCommand(ArduinoCommands.UPLOAD_TOOLBAR, {
isVisible: widget => ArduinoToolbar.is(widget) && widget.side === 'left', isVisible: widget => ArduinoToolbar.is(widget) && widget.side === 'left',
isEnabled: widget => true, execute: this.upload.bind(this)
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);
}
}
}
}); });
registry.registerCommand(ArduinoCommands.SHOW_OPEN_CONTEXT_MENU, { registry.registerCommand(ArduinoCommands.SHOW_OPEN_CONTEXT_MENU, {
isVisible: widget => ArduinoToolbar.is(widget) && widget.side === 'left', isVisible: widget => ArduinoToolbar.is(widget) && widget.side === 'left',
isEnabled: widget => ArduinoToolbar.is(widget) && widget.side === 'left',
execute: async (widget: Widget, target: EventTarget) => { execute: async (widget: Widget, target: EventTarget) => {
if (this.wsSketchCount) { if (this.wsSketchCount) {
const el = (target as HTMLElement).parentElement; const el = (target as HTMLElement).parentElement;
@ -385,7 +317,6 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut
}); });
registry.registerCommand(ArduinoCommands.SAVE_SKETCH, { registry.registerCommand(ArduinoCommands.SAVE_SKETCH, {
isEnabled: widget => ArduinoToolbar.is(widget) && widget.side === 'left',
isVisible: widget => ArduinoToolbar.is(widget) && widget.side === 'left', isVisible: widget => ArduinoToolbar.is(widget) && widget.side === 'left',
execute: async (sketch: Sketch) => { execute: async (sketch: Sketch) => {
registry.executeCommand(CommonCommands.SAVE_ALL.id); registry.executeCommand(CommonCommands.SAVE_ALL.id);
@ -419,13 +350,87 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut
}); });
registry.registerCommand(ArduinoCommands.TOGGLE_ADVANCED_MODE, { registry.registerCommand(ArduinoCommands.TOGGLE_ADVANCED_MODE, {
execute: () => { isToggled: () => this.editorMode.proMode,
this.editorMode.toggleProMode(); execute: () => this.editorMode.toggleProMode()
this.editorMode.menuContentChanged.fire();
},
isVisible: widget => ArduinoToolbar.is(widget) && widget.side === 'right',
isToggled: () => this.editorMode.proMode
}); });
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) { registerMenus(registry: MenuModelRegistry) {

View File

@ -1,9 +1,11 @@
import { injectable } from 'inversify'; import { injectable } from 'inversify';
import { Emitter } from '@theia/core/lib/common/event'; import { Emitter } from '@theia/core/lib/common/event';
import { ApplicationShell, FrontendApplicationContribution, FrontendApplication } from '@theia/core/lib/browser'; import { ApplicationShell, FrontendApplicationContribution, FrontendApplication, Widget } from '@theia/core/lib/browser';
import { ArduinoShellLayoutRestorer } from './shell/arduino-shell-layout-restorer';
import { OutputWidget } from '@theia/output/lib/browser/output-widget'; import { OutputWidget } from '@theia/output/lib/browser/output-widget';
import { EditorWidget } from '@theia/editor/lib/browser'; 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() @injectable()
export class EditorMode implements FrontendApplicationContribution { export class EditorMode implements FrontendApplicationContribution {
@ -31,9 +33,9 @@ export class EditorMode implements FrontendApplicationContribution {
window.localStorage.setItem(EditorMode.PRO_MODE_KEY, String(inAdvancedMode)); window.localStorage.setItem(EditorMode.PRO_MODE_KEY, String(inAdvancedMode));
if (!inAdvancedMode) { if (!inAdvancedMode) {
const { shell } = this.app; 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<ApplicationShell.Area>) { for (const area of ['left', 'right', 'bottom', 'main'] as Array<ApplicationShell.Area>) {
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. // `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); 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 { get compileForDebug(): boolean {
const value = window.localStorage.getItem(EditorMode.COMPILE_FOR_DEBUG_KEY); const value = window.localStorage.getItem(EditorMode.COMPILE_FOR_DEBUG_KEY);
return value === 'true'; return value === 'true';

View File

@ -27,7 +27,7 @@ export class LibraryListWidgetFrontendContribution extends AbstractViewContribut
registerMenus(menus: MenuModelRegistry): void { registerMenus(menus: MenuModelRegistry): void {
if (this.toggleCommand) { if (this.toggleCommand) {
menus.registerMenuAction(ArduinoMenus.SKETCH, { menus.registerMenuAction(ArduinoMenus.TOOLS, {
commandId: this.toggleCommand.id, commandId: this.toggleCommand.id,
label: 'Manage Libraries...' label: 'Manage Libraries...'
}); });

View File

@ -5,8 +5,8 @@ import { MonitorWidget } from "./monitor-widget";
import { MenuModelRegistry, Command, CommandRegistry } from "@theia/core"; import { MenuModelRegistry, Command, CommandRegistry } from "@theia/core";
import { ArduinoMenus } from "../arduino-frontend-contribution"; import { ArduinoMenus } from "../arduino-frontend-contribution";
import { TabBarToolbarContribution, TabBarToolbarRegistry } from "@theia/core/lib/browser/shell/tab-bar-toolbar"; import { TabBarToolbarContribution, TabBarToolbarRegistry } from "@theia/core/lib/browser/shell/tab-bar-toolbar";
import { MonitorModel } from './monitor-model';
import { ArduinoToolbar } from '../toolbar/arduino-toolbar'; import { ArduinoToolbar } from '../toolbar/arduino-toolbar';
import { MonitorModel } from './monitor-model';
export namespace SerialMonitor { export namespace SerialMonitor {
export namespace Commands { export namespace Commands {
@ -29,7 +29,8 @@ export namespace SerialMonitor {
@injectable() @injectable()
export class MonitorViewContribution extends AbstractViewContribution<MonitorWidget> implements TabBarToolbarContribution { export class MonitorViewContribution extends AbstractViewContribution<MonitorWidget> 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; @inject(MonitorModel) protected readonly model: MonitorModel;
@ -40,7 +41,7 @@ export class MonitorViewContribution extends AbstractViewContribution<MonitorWid
defaultWidgetOptions: { defaultWidgetOptions: {
area: 'bottom' area: 'bottom'
}, },
toggleCommandId: MonitorViewContribution.OPEN_SERIAL_MONITOR, toggleCommandId: MonitorViewContribution.TOGGLE_SERIAL_MONITOR,
toggleKeybinding: 'ctrlcmd+shift+m' toggleKeybinding: 'ctrlcmd+shift+m'
}) })
} }
@ -89,8 +90,17 @@ export class MonitorViewContribution extends AbstractViewContribution<MonitorWid
execute: () => this.openView({ execute: () => this.openView({
toggle: true, toggle: true,
activate: 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
})
}); });
} }
} }