mirror of
https://github.com/arduino/arduino-ide.git
synced 2025-10-10 03:48:33 +00:00

It came from the `@theia/debug` extension. Signed-off-by: Akos Kitta <kittaakos@typefox.io>
102 lines
5.8 KiB
TypeScript
102 lines
5.8 KiB
TypeScript
import * as PQueue from 'p-queue';
|
|
import { inject, injectable } from 'inversify';
|
|
import { CommandRegistry } from '@theia/core/lib/common/command';
|
|
import { MenuModelRegistry } from '@theia/core/lib/common/menu';
|
|
import { Disposable, DisposableCollection } from '@theia/core/lib/common/disposable';
|
|
import { BoardsServiceProvider } from './boards-service-provider';
|
|
import { Board, ConfigOption, Programmer } from '../../common/protocol';
|
|
import { FrontendApplicationContribution } from '@theia/core/lib/browser';
|
|
import { BoardsDataStore } from './boards-data-store';
|
|
import { MainMenuManager } from '../../common/main-menu-manager';
|
|
import { ArduinoMenus, unregisterSubmenu } from '../menu/arduino-menus';
|
|
|
|
@injectable()
|
|
export class BoardsDataMenuUpdater implements FrontendApplicationContribution {
|
|
|
|
@inject(CommandRegistry)
|
|
protected readonly commandRegistry: CommandRegistry;
|
|
|
|
@inject(MenuModelRegistry)
|
|
protected readonly menuRegistry: MenuModelRegistry;
|
|
|
|
@inject(MainMenuManager)
|
|
protected readonly mainMenuManager: MainMenuManager;
|
|
|
|
@inject(BoardsDataStore)
|
|
protected readonly boardsDataStore: BoardsDataStore;
|
|
|
|
@inject(BoardsServiceProvider)
|
|
protected readonly boardsServiceClient: BoardsServiceProvider;
|
|
|
|
protected readonly queue = new PQueue({ autoStart: true, concurrency: 1 });
|
|
protected readonly toDisposeOnBoardChange = new DisposableCollection();
|
|
|
|
async onStart(): Promise<void> {
|
|
this.updateMenuActions(this.boardsServiceClient.boardsConfig.selectedBoard);
|
|
this.boardsDataStore.onChanged(() => this.updateMenuActions(this.boardsServiceClient.boardsConfig.selectedBoard));
|
|
this.boardsServiceClient.onBoardsConfigChanged(({ selectedBoard }) => this.updateMenuActions(selectedBoard));
|
|
}
|
|
|
|
protected async updateMenuActions(selectedBoard: Board | undefined): Promise<void> {
|
|
return this.queue.add(async () => {
|
|
this.toDisposeOnBoardChange.dispose();
|
|
this.mainMenuManager.update();
|
|
if (selectedBoard) {
|
|
const { fqbn } = selectedBoard;
|
|
if (fqbn) {
|
|
const { configOptions, programmers, selectedProgrammer } = await this.boardsDataStore.getData(fqbn);
|
|
if (configOptions.length) {
|
|
const boardsConfigMenuPath = [...ArduinoMenus.TOOLS__BOARD_SETTINGS_GROUP, 'z01_boardsConfig']; // `z_` is for ordering.
|
|
for (const { label, option, values } of configOptions.sort(ConfigOption.LABEL_COMPARATOR)) {
|
|
const menuPath = [...boardsConfigMenuPath, `${option}`];
|
|
const commands = new Map<string, Disposable & { label: string }>()
|
|
for (const value of values) {
|
|
const id = `${fqbn}-${option}--${value.value}`;
|
|
const command = { id };
|
|
const selectedValue = value.value;
|
|
const handler = {
|
|
execute: () => this.boardsDataStore.selectConfigOption({ fqbn, option, selectedValue }),
|
|
isToggled: () => value.selected
|
|
};
|
|
commands.set(id, Object.assign(this.commandRegistry.registerCommand(command, handler), { label: value.label }));
|
|
}
|
|
this.menuRegistry.registerSubmenu(menuPath, label);
|
|
this.toDisposeOnBoardChange.pushAll([
|
|
...commands.values(),
|
|
Disposable.create(() => unregisterSubmenu(menuPath, this.menuRegistry)),
|
|
...Array.from(commands.keys()).map((commandId, i) => {
|
|
const { label } = commands.get(commandId)!;
|
|
this.menuRegistry.registerMenuAction(menuPath, { commandId, order: `${i}`, label });
|
|
return Disposable.create(() => this.menuRegistry.unregisterMenuAction(commandId));
|
|
})
|
|
]);
|
|
}
|
|
}
|
|
if (programmers.length) {
|
|
const programmersMenuPath = [...ArduinoMenus.TOOLS__BOARD_SETTINGS_GROUP, 'z02_programmers'];
|
|
const label = selectedProgrammer ? `Programmer: "${selectedProgrammer.name}"` : 'Programmer'
|
|
this.menuRegistry.registerSubmenu(programmersMenuPath, label);
|
|
this.toDisposeOnBoardChange.push(Disposable.create(() => unregisterSubmenu(programmersMenuPath, this.menuRegistry)));
|
|
for (const programmer of programmers) {
|
|
const { id, name } = programmer;
|
|
const command = { id: `${fqbn}-programmer--${id}` };
|
|
const handler = {
|
|
execute: () => this.boardsDataStore.selectProgrammer({ fqbn, selectedProgrammer: programmer }),
|
|
isToggled: () => Programmer.equals(programmer, selectedProgrammer)
|
|
};
|
|
this.menuRegistry.registerMenuAction(programmersMenuPath, { commandId: command.id, label: name });
|
|
this.commandRegistry.registerCommand(command, handler);
|
|
this.toDisposeOnBoardChange.pushAll([
|
|
Disposable.create(() => this.commandRegistry.unregisterCommand(command)),
|
|
Disposable.create(() => this.menuRegistry.unregisterMenuAction(command.id))
|
|
]);
|
|
}
|
|
}
|
|
this.mainMenuManager.update();
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
}
|