Added Open Toolbutton

Signed-off-by: jbicker <jan.bicker@typefox.io>
This commit is contained in:
jbicker 2019-06-17 18:26:24 +02:00
parent 7760915014
commit 0c937212e2
5 changed files with 160 additions and 10 deletions

View File

@ -12,6 +12,19 @@ export namespace ArduinoCommands {
label: 'Upload Sketch'
}
export const SHOW_OPEN_CONTEXT_MENU: Command = {
id: 'arduino-show-open-context-menu',
label: 'Open Sketch'
}
export const OPEN_FILE_NAVIGATOR: Command = {
id: 'arduino-open-file-navigator'
}
export const OPEN_SKETCH: Command = {
id: 'arduino-open-file'
}
export const NEW_SKETCH: Command = {
id: "arduino-new-sketch",
label: 'New Sketch',

View File

@ -1,15 +1,67 @@
import { injectable } from "inversify";
import { MenuContribution, MenuModelRegistry } from "@theia/core";
import { injectable, inject } from "inversify";
import { MenuContribution, MenuModelRegistry, MenuPath, CommandRegistry, Command } from "@theia/core";
import { CommonMenus } from "@theia/core/lib/browser";
import { ArduinoCommands } from "./arduino-commands";
import URI from "@theia/core/lib/common/uri";
export namespace ArduinoOpenSketchContextMenu {
export const PATH: MenuPath = ['arduino-open-sketch-context-menu'];
export const OPEN_GROUP: MenuPath = [...PATH, '1_open'];
export const WS_SKETCHES_GROUP: MenuPath = [...PATH, '2_sketches'];
export const EXAMPLE_SKETCHES_GROUP: MenuPath = [...PATH, '3_examples'];
}
export interface SketchMenuEntry {
name: string,
uri: URI
}
@injectable()
export class ArduinoFileMenuContribution implements MenuContribution {
@inject(CommandRegistry)
protected readonly commands: CommandRegistry;
protected async getWorkspaceSketches(): Promise<SketchMenuEntry[]> {
return [
{
name: 'foo',
uri: new URI('this/is/a/test/uri/foo')
},
{
name: 'bar',
uri: new URI('this/is/a/test/uri/bar')
}
]
}
registerMenus(registry: MenuModelRegistry) {
registry.registerMenuAction([...CommonMenus.FILE, '0_new_sletch'], {
commandId: ArduinoCommands.NEW_SKETCH.id
})
}
registry.registerMenuAction(ArduinoOpenSketchContextMenu.OPEN_GROUP, {
commandId: ArduinoCommands.OPEN_FILE_NAVIGATOR.id,
label: 'Open...'
});
this.getWorkspaceSketches().then(sketches => {
sketches.forEach(sketch => {
const command: Command = {
id: 'openSketch' + sketch.name
}
this.commands.registerCommand(command, {
execute: () => this.commands.executeCommand(ArduinoCommands.OPEN_SKETCH.id, sketch)
});
registry.registerMenuAction(ArduinoOpenSketchContextMenu.WS_SKETCHES_GROUP, {
commandId: command.id,
label: sketch.name
});
})
})
}
}

View File

@ -15,12 +15,16 @@ import { ToolOutputServiceClient } from '../common/protocol/tool-output-service'
import { QuickPickService } from '@theia/core/lib/common/quick-pick-service';
import { BoardsListWidgetFrontendContribution } from './boards/boards-widget-frontend-contribution';
import { BoardsNotificationService } from './boards-notification-service';
import { WorkspaceRootUriAwareCommandHandler } from '@theia/workspace/lib/browser/workspace-commands';
import { WorkspaceRootUriAwareCommandHandler, WorkspaceCommands } from '@theia/workspace/lib/browser/workspace-commands';
import { SelectionService } from '@theia/core';
import { WorkspaceService } from '@theia/workspace/lib/browser/workspace-service';
import { SketchFactory } from './sketch-factory';
import { ArduinoToolbar } from './toolbar/arduino-toolbar';
import { EditorManager } from '@theia/editor/lib/browser';
import { open, ContextMenuRenderer, OpenerService, Widget } from '@theia/core/lib/browser';
import { OpenFileDialogProps, FileDialogService } from '@theia/filesystem/lib/browser/file-dialog';
import { FileSystem } from '@theia/filesystem/lib/common';
import { ArduinoOpenSketchContextMenu, SketchMenuEntry } from './arduino-file-menu';
@injectable()
export class ArduinoFrontendContribution extends DefaultFrontendApplicationContribution implements TabBarToolbarContribution, CommandContribution {
@ -61,6 +65,18 @@ export class ArduinoFrontendContribution extends DefaultFrontendApplicationContr
@inject(EditorManager)
protected readonly editorManager: EditorManager;
@inject(ContextMenuRenderer)
protected readonly contextMenuRenderer: ContextMenuRenderer;
@inject(FileDialogService)
protected readonly fileDialogService: FileDialogService;
@inject(FileSystem)
protected readonly fileSystem: FileSystem;
@inject(OpenerService)
protected readonly openerService: OpenerService;
@postConstruct()
protected async init(): Promise<void> {
// This is a hack. Otherwise, the backend services won't bind.
@ -82,6 +98,13 @@ export class ArduinoFrontendContribution extends DefaultFrontendApplicationContr
group: 'arduino',
text: '$(arrow-right)'
});
registry.registerItem({
id: ArduinoCommands.SHOW_OPEN_CONTEXT_MENU.id,
command: ArduinoCommands.SHOW_OPEN_CONTEXT_MENU.id,
tooltip: 'Open',
group: 'arduino',
text: '$(arrow-up)'
});
registry.registerItem({
id: ConnectedBoards.TOOLBAR_ID,
render: () => <ConnectedBoards
@ -137,6 +160,29 @@ export class ArduinoFrontendContribution extends DefaultFrontendApplicationContr
}
}
});
registry.registerCommand(ArduinoCommands.SHOW_OPEN_CONTEXT_MENU, {
isVisible: widget => this.isArduinoToolbar(widget),
isEnabled: widget => this.isArduinoToolbar(widget),
execute: async (widget: Widget, event: React.MouseEvent<HTMLElement>) => {
const el = (event.target as HTMLElement).parentElement;
if(el) {
this.contextMenuRenderer.render(ArduinoOpenSketchContextMenu.PATH, {
x: el.getBoundingClientRect().left,
y: el.getBoundingClientRect().top + el.offsetHeight
});
}
}
});
registry.registerCommand(ArduinoCommands.OPEN_FILE_NAVIGATOR, {
isEnabled: () => true,
execute: () => this.doOpenFile()
})
registry.registerCommand(ArduinoCommands.OPEN_SKETCH, {
isEnabled: () => true,
execute: (sketch: SketchMenuEntry) => {
console.log("OPEN SOME SKETCH", sketch);
}
})
registry.registerCommand(ArduinoCommands.NEW_SKETCH, new WorkspaceRootUriAwareCommandHandler(this.workspaceService, this.selectionService, {
execute: async uri => {
try {
@ -157,6 +203,32 @@ export class ArduinoFrontendContribution extends DefaultFrontendApplicationContr
})
}
/**
* Opens a file after prompting the `Open File` dialog. Resolves to `undefined`, if
* - the workspace root is not set,
* - the file to open does not exist, or
* - it was not a file, but a directory.
*
* Otherwise, resolves to the URI of the file.
*/
protected async doOpenFile(): Promise<URI | undefined> {
const props: OpenFileDialogProps = {
title: WorkspaceCommands.OPEN_FILE.dialogLabel,
canSelectFolders: false,
canSelectFiles: true
};
const [rootStat] = await this.workspaceService.roots;
const destinationFileUri = await this.fileDialogService.showOpenDialog(props, rootStat);
if (destinationFileUri) {
const destinationFile = await this.fileSystem.getFileStat(destinationFileUri.toString());
if (destinationFile && !destinationFile.isDirectory) {
await open(this.openerService, destinationFileUri);
return destinationFileUri;
}
}
return undefined;
}
protected getCurrentWidget(): EditorWidget | undefined {
let widget = this.editorManager.currentEditor;
if (!widget) {

View File

@ -13,15 +13,22 @@
#arduino-verify.arduino-tool-icon {
background: url(../icons/buttons.svg);
background-size: 800%;
background-position-x: 141px;
background-position-y: 21px;
background-position-x: 141px;
}
#arduino-upload.arduino-tool-icon {
background: url(../icons/buttons.svg);
background-size: 800%;
background-position-x: 117px;
background-position-y: 21px;
background-position-x: 117px;
}
#arduino-show-open-context-menu.arduino-tool-icon {
background: url(../icons/buttons.svg);
background-size: 800%;
background-position-y: 21px;
background-position-x: 69px;
}
#arduino-verify.arduino-tool-icon:hover {

View File

@ -26,14 +26,13 @@ export class ArduinoToolbarComponent extends React.Component<ArduinoToolbarCompo
protected renderItem(item: TabBarToolbarItem): React.ReactNode {
let innerText = '';
const command = this.props.commands.getCommand(item.command);
const cls = `${ARDUINO_TOOLBAR_ITEM_CLASS} ${TabBarToolbar.Styles.TAB_BAR_TOOLBAR_ITEM} ${command && this.props.commandIsEnabled(command.id) ? ' enabled' : ''}`
return <React.Fragment>
<div key={item.id}
className={`${ARDUINO_TOOLBAR_ITEM_CLASS}
${TabBarToolbar.Styles.TAB_BAR_TOOLBAR_ITEM}
${command && this.props.commandIsEnabled(command.id) ? ' enabled' : ''}`} >
className={cls} >
<div
id={item.id}
className='arduino-tool-icon'
className={`${item.id} arduino-tool-icon`}
onClick={this.props.executeCommand}
onMouseOver={() => this.setState({ tootip: item.tooltip || '' })}
onMouseOut={() => this.setState({ tootip: '' })}
@ -84,4 +83,11 @@ export class ArduinoToolbar extends TabBarToolbar {
/>
}
protected executeCommand = (e: React.MouseEvent<HTMLElement>) => {
const item = this.items.get(e.currentTarget.id);
if (TabBarToolbarItem.is(item)) {
this.commands.executeCommand(item.command, this, e);
}
}
}