mirror of
https://github.com/arduino/arduino-ide.git
synced 2025-11-13 20:29:27 +00:00
ATL-73: Added library examples to the app.
Signed-off-by: Akos Kitta <kittaakos@typefox.io>
This commit is contained in:
@@ -119,7 +119,7 @@ import { OutputWidget as TheiaOutputWidget } from '@theia/output/lib/browser/out
|
||||
import { OutputWidget } from './theia/output/output-widget';
|
||||
import { BurnBootloader } from './contributions/burn-bootloader';
|
||||
import { ExamplesServicePath, ExamplesService } from '../common/protocol/examples-service';
|
||||
import { Examples } from './contributions/examples';
|
||||
import { BuiltInExamples, LibraryExamples } from './contributions/examples';
|
||||
import { LibraryServiceProvider } from './library/library-service-provider';
|
||||
import { IncludeLibrary } from './contributions/include-library';
|
||||
import { IncludeLibraryMenuUpdater } from './library/include-library-menu-updater';
|
||||
@@ -371,6 +371,7 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
Contribution.configure(bind, SketchControl);
|
||||
Contribution.configure(bind, Settings);
|
||||
Contribution.configure(bind, BurnBootloader);
|
||||
Contribution.configure(bind, Examples);
|
||||
Contribution.configure(bind, BuiltInExamples);
|
||||
Contribution.configure(bind, LibraryExamples);
|
||||
Contribution.configure(bind, IncludeLibrary);
|
||||
});
|
||||
|
||||
@@ -1,20 +1,16 @@
|
||||
import { inject, injectable } from 'inversify';
|
||||
import { inject, injectable, postConstruct } from 'inversify';
|
||||
import { MenuPath, SubMenuOptions } from '@theia/core/lib/common/menu';
|
||||
import { Disposable, DisposableCollection } from '@theia/core/lib/common/disposable';
|
||||
import { OpenSketch } from './open-sketch';
|
||||
import { ArduinoMenus } from '../menu/arduino-menus';
|
||||
import { MainMenuManager } from '../../common/main-menu-manager';
|
||||
import { LibraryServiceProvider } from '../library/library-service-provider';
|
||||
import { BoardsServiceClientImpl } from '../boards/boards-service-client-impl';
|
||||
import { ExamplesService, ExampleContainer } from '../../common/protocol/examples-service';
|
||||
import { SketchContribution, CommandRegistry, MenuModelRegistry } from './contribution';
|
||||
|
||||
@injectable()
|
||||
export class Examples extends SketchContribution {
|
||||
|
||||
@inject(MainMenuManager)
|
||||
protected readonly menuManager: MainMenuManager;
|
||||
|
||||
@inject(ExamplesService)
|
||||
protected readonly examplesService: ExamplesService;
|
||||
export abstract class Examples extends SketchContribution {
|
||||
|
||||
@inject(CommandRegistry)
|
||||
protected readonly commandRegistry: CommandRegistry;
|
||||
@@ -22,26 +18,30 @@ export class Examples extends SketchContribution {
|
||||
@inject(MenuModelRegistry)
|
||||
protected readonly menuRegistry: MenuModelRegistry;
|
||||
|
||||
protected readonly toDisposeBeforeRegister = new DisposableCollection();
|
||||
@inject(MainMenuManager)
|
||||
protected readonly menuManager: MainMenuManager;
|
||||
|
||||
onStart(): void {
|
||||
this.registerExamples(); // no `await`
|
||||
@inject(ExamplesService)
|
||||
protected readonly examplesService: ExamplesService;
|
||||
|
||||
@inject(BoardsServiceClientImpl)
|
||||
protected readonly boardsServiceClient: BoardsServiceClientImpl;
|
||||
|
||||
protected readonly toDispose = new DisposableCollection();
|
||||
|
||||
@postConstruct()
|
||||
init(): void {
|
||||
this.boardsServiceClient.onBoardsConfigChanged(({ selectedBoard }) => this.handleBoardChanged(selectedBoard?.fqbn));
|
||||
}
|
||||
|
||||
protected async registerExamples() {
|
||||
let exampleContainer: ExampleContainer | undefined;
|
||||
try {
|
||||
exampleContainer = await this.examplesService.all();
|
||||
} catch (e) {
|
||||
console.error('Could not initialize built-in examples.', e);
|
||||
}
|
||||
if (!exampleContainer) {
|
||||
this.messageService.error('Could not initialize built-in examples.');
|
||||
return;
|
||||
}
|
||||
this.toDisposeBeforeRegister.dispose();
|
||||
this.registerRecursively(exampleContainer, ArduinoMenus.FILE__SKETCH_GROUP, this.toDisposeBeforeRegister, { order: '4' });
|
||||
this.menuManager.update();
|
||||
protected handleBoardChanged(fqbn: string | undefined): void {
|
||||
// NOOP
|
||||
}
|
||||
|
||||
registerMenus(registry: MenuModelRegistry): void {
|
||||
// Registering the same submenu multiple times has no side-effect.
|
||||
// TODO: unregister submenu? https://github.com/eclipse-theia/theia/issues/7300
|
||||
registry.registerSubmenu(ArduinoMenus.FILE__EXAMPLES_SUBMENU, 'Examples', { order: '4' });
|
||||
}
|
||||
|
||||
registerRecursively(
|
||||
@@ -52,7 +52,6 @@ export class Examples extends SketchContribution {
|
||||
|
||||
const { label, sketches, children } = exampleContainer;
|
||||
const submenuPath = [...menuPath, label];
|
||||
// TODO: unregister submenu? https://github.com/eclipse-theia/theia/issues/7300
|
||||
this.menuRegistry.registerSubmenu(submenuPath, label, options);
|
||||
children.forEach(child => this.registerRecursively(child, submenuPath, pushToDispose));
|
||||
for (const sketch of sketches) {
|
||||
@@ -72,3 +71,68 @@ export class Examples extends SketchContribution {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@injectable()
|
||||
export class BuiltInExamples extends Examples {
|
||||
|
||||
onStart(): void {
|
||||
this.register(); // no `await`
|
||||
}
|
||||
|
||||
protected async register() {
|
||||
let exampleContainers: ExampleContainer[] | undefined;
|
||||
try {
|
||||
exampleContainers = await this.examplesService.builtIns();
|
||||
} catch (e) {
|
||||
console.error('Could not initialize built-in examples.', e);
|
||||
this.messageService.error('Could not initialize built-in examples.');
|
||||
return;
|
||||
}
|
||||
this.toDispose.dispose();
|
||||
for (const container of exampleContainers) {
|
||||
this.registerRecursively(container, ArduinoMenus.EXAMPLES__BUILT_IN_GROUP, this.toDispose);
|
||||
}
|
||||
this.menuManager.update();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@injectable()
|
||||
export class LibraryExamples extends Examples {
|
||||
|
||||
@inject(LibraryServiceProvider)
|
||||
protected readonly libraryServiceProvider: LibraryServiceProvider;
|
||||
|
||||
protected readonly queue = new PQueue({ autoStart: true, concurrency: 1 });
|
||||
|
||||
onStart(): void {
|
||||
this.register(); // no `await`
|
||||
this.libraryServiceProvider.onLibraryPackageInstalled(() => this.register());
|
||||
this.libraryServiceProvider.onLibraryPackageUninstalled(() => this.register());
|
||||
}
|
||||
|
||||
protected handleBoardChanged(fqbn: string | undefined): void {
|
||||
this.register(fqbn);
|
||||
}
|
||||
|
||||
protected async register(fqbn: string | undefined = this.boardsServiceClient.boardsConfig.selectedBoard?.fqbn) {
|
||||
return this.queue.add(async () => {
|
||||
this.toDispose.dispose();
|
||||
if (!fqbn) {
|
||||
return;
|
||||
}
|
||||
const { user, current, any } = await this.examplesService.installed({ fqbn });
|
||||
for (const container of user) {
|
||||
this.registerRecursively(container, ArduinoMenus.EXAMPLES__USER_LIBS_GROUP, this.toDispose);
|
||||
}
|
||||
for (const container of current) {
|
||||
this.registerRecursively(container, ArduinoMenus.EXAMPLES__CURRENT_BOARD_GROUP, this.toDispose);
|
||||
}
|
||||
for (const container of any) {
|
||||
this.registerRecursively(container, ArduinoMenus.EXAMPLES__ANY_BOARD_GROUP, this.toDispose);
|
||||
}
|
||||
this.menuManager.update();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import { ArduinoMenus } from '../menu/arduino-menus';
|
||||
import { ArduinoToolbar } from '../toolbar/arduino-toolbar';
|
||||
import { SketchContribution, Sketch, URI, Command, CommandRegistry, MenuModelRegistry, KeybindingRegistry, TabBarToolbarRegistry } from './contribution';
|
||||
import { ExamplesService } from '../../common/protocol/examples-service';
|
||||
import { Examples } from './examples';
|
||||
import { BuiltInExamples } from './examples';
|
||||
|
||||
@injectable()
|
||||
export class OpenSketch extends SketchContribution {
|
||||
@@ -18,8 +18,8 @@ export class OpenSketch extends SketchContribution {
|
||||
@inject(ContextMenuRenderer)
|
||||
protected readonly contextMenuRenderer: ContextMenuRenderer;
|
||||
|
||||
@inject(Examples)
|
||||
protected readonly examples: Examples;
|
||||
@inject(BuiltInExamples)
|
||||
protected readonly builtInExamples: BuiltInExamples;
|
||||
|
||||
@inject(ExamplesService)
|
||||
protected readonly examplesService: ExamplesService;
|
||||
@@ -62,9 +62,9 @@ export class OpenSketch extends SketchContribution {
|
||||
this.toDisposeBeforeCreateNewContextMenu.push(Disposable.create(() => this.menuRegistry.unregisterMenuAction(command)));
|
||||
}
|
||||
try {
|
||||
const { children } = await this.examplesService.all();
|
||||
for (const child of children) {
|
||||
this.examples.registerRecursively(child, ArduinoMenus.OPEN_SKETCH__CONTEXT__EXAMPLES_GROUP, this.toDisposeBeforeCreateNewContextMenu);
|
||||
const containers = await this.examplesService.builtIns();
|
||||
for (const container of containers) {
|
||||
this.builtInExamples.registerRecursively(container, ArduinoMenus.OPEN_SKETCH__CONTEXT__EXAMPLES_GROUP, this.toDisposeBeforeCreateNewContextMenu);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Error when collecting built-in examples.', e);
|
||||
|
||||
@@ -44,8 +44,12 @@ export class IncludeLibraryMenuUpdater implements FrontendApplicationContributio
|
||||
return this.queue.add(async () => {
|
||||
this.toDispose.dispose();
|
||||
this.mainMenuManager.update();
|
||||
const libraries: LibraryPackage[] = []
|
||||
const fqbn = this.boardsServiceClient.boardsConfig.selectedBoard?.fqbn;
|
||||
const libraries = await this.libraryServiceProvider.list({ fqbn });
|
||||
// Do not show board specific examples, when no board is selected.
|
||||
if (fqbn) {
|
||||
libraries.push(...await this.libraryServiceProvider.list({ fqbn }));
|
||||
}
|
||||
|
||||
// `Include Library` submenu
|
||||
const includeLibMenuPath = [...ArduinoMenus.SKETCH__UTILS_GROUP, '0_include'];
|
||||
|
||||
@@ -12,6 +12,13 @@ export namespace ArduinoMenus {
|
||||
export const FILE__SETTINGS_GROUP = [...(isOSX ? MAIN_MENU_BAR : CommonMenus.FILE), '2_settings'];
|
||||
export const FILE__QUIT_GROUP = [...CommonMenus.FILE, '3_quit'];
|
||||
|
||||
// -- File / Examples
|
||||
export const FILE__EXAMPLES_SUBMENU = [...FILE__SKETCH_GROUP, '0_examples'];
|
||||
export const EXAMPLES__BUILT_IN_GROUP = [...FILE__EXAMPLES_SUBMENU, '0_built_ins'];
|
||||
export const EXAMPLES__ANY_BOARD_GROUP = [...FILE__EXAMPLES_SUBMENU, '1_any_board'];
|
||||
export const EXAMPLES__CURRENT_BOARD_GROUP = [...FILE__EXAMPLES_SUBMENU, '2_current_board'];
|
||||
export const EXAMPLES__USER_LIBS_GROUP = [...FILE__EXAMPLES_SUBMENU, '3_user_libs'];
|
||||
|
||||
// -- Edit
|
||||
// `Copy`, `Copy to Forum`, `Paste`, etc.
|
||||
// Note: `1_undo` is the first group from Theia, we start with `2`
|
||||
|
||||
Reference in New Issue
Block a user