mirror of
https://github.com/arduino/arduino-ide.git
synced 2025-06-19 10:36:33 +00:00
Merge pull request #37 from bcmi-labs/board-selector-toolbar-item
Board selector toolbar item
This commit is contained in:
commit
269f08b74d
@ -1,78 +1,25 @@
|
|||||||
import { injectable, inject } from "inversify";
|
import { injectable, inject } from "inversify";
|
||||||
import { MenuContribution, MenuModelRegistry, MenuPath, CommandRegistry, Command } from "@theia/core";
|
import { MenuContribution, MenuModelRegistry, MenuPath } from "@theia/core";
|
||||||
import { CommonMenus } from "@theia/core/lib/browser";
|
import { CommonMenus } from "@theia/core/lib/browser";
|
||||||
import { ArduinoCommands } from "./arduino-commands";
|
import { ArduinoCommands } from "./arduino-commands";
|
||||||
import { SketchesService, Sketch } from "../common/protocol/sketches-service";
|
|
||||||
import { AWorkspaceService } from "./arduino-workspace-service";
|
|
||||||
import { BoardsService } from "../common/protocol/boards-service";
|
|
||||||
|
|
||||||
export namespace ArduinoToolbarContextMenu {
|
export namespace ArduinoToolbarContextMenu {
|
||||||
export const OPEN_SKETCH_PATH: MenuPath = ['arduino-open-sketch-context-menu'];
|
export const OPEN_SKETCH_PATH: MenuPath = ['arduino-open-sketch-context-menu'];
|
||||||
export const OPEN_GROUP: MenuPath = [...OPEN_SKETCH_PATH, '1_open'];
|
export const OPEN_GROUP: MenuPath = [...OPEN_SKETCH_PATH, '1_open'];
|
||||||
export const WS_SKETCHES_GROUP: MenuPath = [...OPEN_SKETCH_PATH, '2_sketches'];
|
export const WS_SKETCHES_GROUP: MenuPath = [...OPEN_SKETCH_PATH, '2_sketches'];
|
||||||
export const EXAMPLE_SKETCHES_GROUP: MenuPath = [...OPEN_SKETCH_PATH, '3_examples'];
|
export const EXAMPLE_SKETCHES_GROUP: MenuPath = [...OPEN_SKETCH_PATH, '3_examples'];
|
||||||
|
|
||||||
export const SELECT_BOARDS_PATH: MenuPath = ['arduino-select-boards-context-menu'];
|
|
||||||
export const CONNECTED_GROUP: MenuPath = [...SELECT_BOARDS_PATH, '1_connected'];
|
|
||||||
export const OPEN_BOARDS_DIALOG_GROUP: MenuPath = [...SELECT_BOARDS_PATH, '2_open_boards_dialog'];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
export class ArduinoToolbarMenuContribution implements MenuContribution {
|
export class ArduinoToolbarMenuContribution implements MenuContribution {
|
||||||
|
|
||||||
@inject(CommandRegistry)
|
|
||||||
protected readonly commands: CommandRegistry;
|
|
||||||
|
|
||||||
@inject(SketchesService)
|
|
||||||
protected readonly sketches: SketchesService;
|
|
||||||
|
|
||||||
@inject(BoardsService)
|
|
||||||
protected readonly boardsService: BoardsService;
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@inject(AWorkspaceService) protected readonly workspaceService: AWorkspaceService,
|
|
||||||
@inject(MenuModelRegistry) protected readonly menuRegistry: MenuModelRegistry) {
|
@inject(MenuModelRegistry) protected readonly menuRegistry: MenuModelRegistry) {
|
||||||
workspaceService.onWorkspaceChanged(() => {
|
|
||||||
if (this.workspaceService.workspace) {
|
|
||||||
this.registerSketchesInMenu(menuRegistry);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
protected async registerSketchesInMenu(registry: MenuModelRegistry) {
|
|
||||||
const sketches = await this.getWorkspaceSketches();
|
|
||||||
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(ArduinoToolbarContextMenu.WS_SKETCHES_GROUP, {
|
|
||||||
commandId: command.id,
|
|
||||||
label: sketch.name
|
|
||||||
});
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
protected async getWorkspaceSketches(): Promise<Sketch[]> {
|
|
||||||
const sketches = this.sketches.getSketches(this.workspaceService.workspace);
|
|
||||||
return sketches;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
registerMenus(registry: MenuModelRegistry) {
|
registerMenus(registry: MenuModelRegistry) {
|
||||||
registry.registerMenuAction([...CommonMenus.FILE, '0_new_sletch'], {
|
registry.registerMenuAction([...CommonMenus.FILE, '0_new_sletch'], {
|
||||||
commandId: ArduinoCommands.NEW_SKETCH.id
|
commandId: ArduinoCommands.NEW_SKETCH.id
|
||||||
});
|
})
|
||||||
|
|
||||||
registry.registerMenuAction(ArduinoToolbarContextMenu.OPEN_GROUP, {
|
|
||||||
commandId: ArduinoCommands.OPEN_FILE_NAVIGATOR.id,
|
|
||||||
label: 'Open...'
|
|
||||||
});
|
|
||||||
|
|
||||||
registry.registerMenuAction(ArduinoToolbarContextMenu.OPEN_BOARDS_DIALOG_GROUP, {
|
|
||||||
commandId: ArduinoCommands.OPEN_BOARDS_DIALOG.id,
|
|
||||||
label: 'Select Other Board & Port'
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -5,7 +5,7 @@ import { EditorWidget } from '@theia/editor/lib/browser/editor-widget';
|
|||||||
import { MessageService } from '@theia/core/lib/common/message-service';
|
import { MessageService } from '@theia/core/lib/common/message-service';
|
||||||
import { CommandContribution, CommandRegistry, Command } from '@theia/core/lib/common/command';
|
import { CommandContribution, CommandRegistry, Command } from '@theia/core/lib/common/command';
|
||||||
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 { BoardsService, Board, AttachedSerialBoard } from '../common/protocol/boards-service';
|
import { BoardsService, Board } from '../common/protocol/boards-service';
|
||||||
import { ArduinoCommands } from './arduino-commands';
|
import { ArduinoCommands } from './arduino-commands';
|
||||||
import { ConnectedBoards } from './components/connected-boards';
|
import { ConnectedBoards } from './components/connected-boards';
|
||||||
import { CoreService } from '../common/protocol/core-service';
|
import { CoreService } from '../common/protocol/core-service';
|
||||||
@ -66,9 +66,6 @@ export class ArduinoFrontendContribution implements TabBarToolbarContribution, C
|
|||||||
@inject(BoardsNotificationService)
|
@inject(BoardsNotificationService)
|
||||||
protected readonly boardsNotificationService: BoardsNotificationService;
|
protected readonly boardsNotificationService: BoardsNotificationService;
|
||||||
|
|
||||||
@inject(WorkspaceService)
|
|
||||||
protected readonly workspaceService: WorkspaceService;
|
|
||||||
|
|
||||||
@inject(SelectionService)
|
@inject(SelectionService)
|
||||||
protected readonly selectionService: SelectionService;
|
protected readonly selectionService: SelectionService;
|
||||||
|
|
||||||
@ -106,48 +103,20 @@ export class ArduinoFrontendContribution implements TabBarToolbarContribution, C
|
|||||||
protected readonly commands: CommandRegistry;
|
protected readonly commands: CommandRegistry;
|
||||||
|
|
||||||
protected boardsToolbarItem: BoardsToolBarItem | null;
|
protected boardsToolbarItem: BoardsToolBarItem | null;
|
||||||
protected attachedBoards: Board[];
|
protected wsSketchCount: number = 0;
|
||||||
protected selectedBoard: Board;
|
|
||||||
|
constructor(@inject(WorkspaceService) protected readonly workspaceService: WorkspaceService) {
|
||||||
|
this.workspaceService.onWorkspaceChanged(() => {
|
||||||
|
if (this.workspaceService.workspace) {
|
||||||
|
this.registerSketchesInMenu(this.menuRegistry);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
@postConstruct()
|
@postConstruct()
|
||||||
protected async init(): Promise<void> {
|
protected async init(): Promise<void> {
|
||||||
// This is a hack. Otherwise, the backend services won't bind.
|
// This is a hack. Otherwise, the backend services won't bind.
|
||||||
await this.workspaceServiceExt.roots();
|
await this.workspaceServiceExt.roots();
|
||||||
const { boards } = await this.boardService.getAttachedBoards();
|
|
||||||
this.attachedBoards = boards;
|
|
||||||
this.registerConnectedBoardsInMenu(this.menuRegistry);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected async registerConnectedBoardsInMenu(registry: MenuModelRegistry) {
|
|
||||||
this.attachedBoards.forEach(board => {
|
|
||||||
const port = this.getPort(board);
|
|
||||||
const command: Command = {
|
|
||||||
id: 'selectBoard' + port
|
|
||||||
}
|
|
||||||
this.commands.registerCommand(command, {
|
|
||||||
execute: () => this.commands.executeCommand(ArduinoCommands.SELECT_BOARD.id, board),
|
|
||||||
isToggled: () => this.isSelectedBoard(board)
|
|
||||||
});
|
|
||||||
registry.registerMenuAction(ArduinoToolbarContextMenu.CONNECTED_GROUP, {
|
|
||||||
commandId: command.id,
|
|
||||||
label: board.name + ' at ' + port
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
protected isSelectedBoard(board: Board): boolean {
|
|
||||||
return AttachedSerialBoard.is(board) &&
|
|
||||||
this.selectedBoard &&
|
|
||||||
AttachedSerialBoard.is(this.selectedBoard) &&
|
|
||||||
board.port === this.selectedBoard.port &&
|
|
||||||
board.fqbn === this.selectedBoard.fqbn;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected getPort(board: Board): string {
|
|
||||||
if (AttachedSerialBoard.is(board)) {
|
|
||||||
return board.port;
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
registerToolbarItems(registry: TabBarToolbarRegistry): void {
|
registerToolbarItems(registry: TabBarToolbarRegistry): void {
|
||||||
@ -178,7 +147,9 @@ export class ArduinoFrontendContribution implements TabBarToolbarContribution, C
|
|||||||
registry.registerItem({
|
registry.registerItem({
|
||||||
id: ConnectedBoards.TOOLBAR_ID,
|
id: ConnectedBoards.TOOLBAR_ID,
|
||||||
render: () => <BoardsToolBarItem
|
render: () => <BoardsToolBarItem
|
||||||
|
key='boardsToolbarItem'
|
||||||
ref={ref => this.boardsToolbarItem = ref}
|
ref={ref => this.boardsToolbarItem = ref}
|
||||||
|
commands={this.commands}
|
||||||
contextMenuRenderer={this.contextMenuRenderer}
|
contextMenuRenderer={this.contextMenuRenderer}
|
||||||
boardsNotificationService={this.boardsNotificationService}
|
boardsNotificationService={this.boardsNotificationService}
|
||||||
boardService={this.boardService} />,
|
boardService={this.boardService} />,
|
||||||
@ -233,12 +204,16 @@ export class ArduinoFrontendContribution implements TabBarToolbarContribution, C
|
|||||||
isVisible: widget => this.isArduinoToolbar(widget),
|
isVisible: widget => this.isArduinoToolbar(widget),
|
||||||
isEnabled: widget => this.isArduinoToolbar(widget),
|
isEnabled: widget => this.isArduinoToolbar(widget),
|
||||||
execute: async (widget: Widget, target: EventTarget) => {
|
execute: async (widget: Widget, target: EventTarget) => {
|
||||||
const el = (target as HTMLElement).parentElement;
|
if (this.wsSketchCount) {
|
||||||
if (el) {
|
const el = (target as HTMLElement).parentElement;
|
||||||
this.contextMenuRenderer.render(ArduinoToolbarContextMenu.OPEN_SKETCH_PATH, {
|
if (el) {
|
||||||
x: el.getBoundingClientRect().left,
|
this.contextMenuRenderer.render(ArduinoToolbarContextMenu.OPEN_SKETCH_PATH, {
|
||||||
y: el.getBoundingClientRect().top + el.offsetHeight
|
x: el.getBoundingClientRect().left,
|
||||||
});
|
y: el.getBoundingClientRect().top + el.offsetHeight
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.commands.executeCommand(ArduinoCommands.OPEN_FILE_NAVIGATOR.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -295,11 +270,10 @@ export class ArduinoFrontendContribution implements TabBarToolbarContribution, C
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected async selectBoard(board: Board) {
|
protected async selectBoard(board: Board) {
|
||||||
await this.boardService.selectBoard(board)
|
await this.boardService.selectBoard(board);
|
||||||
if (this.boardsToolbarItem) {
|
if (this.boardsToolbarItem) {
|
||||||
this.boardsToolbarItem.setSelectedBoard(board);
|
this.boardsToolbarItem.setSelectedBoard(board);
|
||||||
}
|
}
|
||||||
this.selectedBoard = board;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
registerMenus(registry: MenuModelRegistry) {
|
registerMenus(registry: MenuModelRegistry) {
|
||||||
@ -332,6 +306,10 @@ export class ArduinoFrontendContribution implements TabBarToolbarContribution, C
|
|||||||
label: 'Upload',
|
label: 'Upload',
|
||||||
order: '2'
|
order: '2'
|
||||||
});
|
});
|
||||||
|
registry.registerMenuAction(ArduinoToolbarContextMenu.OPEN_GROUP, {
|
||||||
|
commandId: ArduinoCommands.OPEN_FILE_NAVIGATOR.id,
|
||||||
|
label: 'Open...'
|
||||||
|
});
|
||||||
|
|
||||||
registry.registerSubmenu(ArduinoMenus.TOOLS, 'Tools');
|
registry.registerSubmenu(ArduinoMenus.TOOLS, 'Tools');
|
||||||
}
|
}
|
||||||
@ -342,6 +320,30 @@ export class ArduinoFrontendContribution implements TabBarToolbarContribution, C
|
|||||||
return menuId;
|
return menuId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected registerSketchesInMenu(registry: MenuModelRegistry) {
|
||||||
|
this.getWorkspaceSketches().then(sketches => {
|
||||||
|
this.wsSketchCount = sketches.length;
|
||||||
|
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(ArduinoToolbarContextMenu.WS_SKETCHES_GROUP, {
|
||||||
|
commandId: command.id,
|
||||||
|
label: sketch.name
|
||||||
|
});
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async getWorkspaceSketches(): Promise<Sketch[]> {
|
||||||
|
const sketches = this.sketches.getSketches(this.workspaceService.workspace);
|
||||||
|
return sketches;
|
||||||
|
}
|
||||||
|
|
||||||
protected async openSketchFilesInNewWindow(uri: string) {
|
protected async openSketchFilesInNewWindow(uri: string) {
|
||||||
const location = new URL(window.location.href);
|
const location = new URL(window.location.href);
|
||||||
location.searchParams.set('sketch', uri);
|
location.searchParams.set('sketch', uri);
|
||||||
|
@ -1,48 +1,135 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { BoardsService, Board } from '../../common/protocol/boards-service';
|
import { BoardsService, Board, AttachedSerialBoard } from '../../common/protocol/boards-service';
|
||||||
import { ContextMenuRenderer } from '@theia/core/lib/browser';
|
import { ContextMenuRenderer } from '@theia/core/lib/browser';
|
||||||
import { ArduinoToolbarContextMenu } from '../arduino-file-menu';
|
|
||||||
import { BoardsNotificationService } from '../boards-notification-service';
|
import { BoardsNotificationService } from '../boards-notification-service';
|
||||||
|
import { Command, CommandRegistry } from '@theia/core';
|
||||||
|
import { ArduinoCommands } from '../arduino-commands';
|
||||||
|
import ReactDOM = require('react-dom');
|
||||||
|
|
||||||
|
export interface BoardsDropdownItem {
|
||||||
|
label: string;
|
||||||
|
commandExecutor: () => void;
|
||||||
|
isSelected: () => boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BoardsDropDownListCoord {
|
||||||
|
top: number;
|
||||||
|
left: number;
|
||||||
|
width: number;
|
||||||
|
paddingTop: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace BoardsDropdownItemComponent {
|
||||||
|
export interface Props {
|
||||||
|
label: string;
|
||||||
|
onClick: () => void;
|
||||||
|
isSelected: boolean;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class BoardsDropdownItemComponent extends React.Component<BoardsDropdownItemComponent.Props> {
|
||||||
|
render() {
|
||||||
|
return <div className={`arduino-boards-dropdown-item ${this.props.isSelected ? 'selected' : ''}`} onClick={this.props.onClick}>
|
||||||
|
<div>{this.props.label}</div>
|
||||||
|
{this.props.isSelected ? <span className='fa fa-check'></span> : ''}
|
||||||
|
</div>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace BoardsDropDown {
|
||||||
|
export interface Props {
|
||||||
|
readonly coords: BoardsDropDownListCoord;
|
||||||
|
readonly isOpen: boolean;
|
||||||
|
readonly dropDownItems: BoardsDropdownItem[];
|
||||||
|
readonly openDialog: () => void;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class BoardsDropDown extends React.Component<BoardsDropDown.Props> {
|
||||||
|
protected dropdownId: string = 'boards-dropdown-container';
|
||||||
|
protected dropdownElement: HTMLElement;
|
||||||
|
|
||||||
|
constructor(props: BoardsDropDown.Props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
let list = document.getElementById(this.dropdownId);
|
||||||
|
if (!list) {
|
||||||
|
list = document.createElement('div');
|
||||||
|
list.id = this.dropdownId;
|
||||||
|
document.body.appendChild(list);
|
||||||
|
this.dropdownElement = list;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render(): React.ReactNode {
|
||||||
|
return ReactDOM.createPortal(this.renderNode(), this.dropdownElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderNode(): React.ReactNode {
|
||||||
|
if (this.props.isOpen) {
|
||||||
|
return <div className='arduino-boards-dropdown-list'
|
||||||
|
style={{
|
||||||
|
position: 'absolute',
|
||||||
|
top: this.props.coords.top,
|
||||||
|
left: this.props.coords.left,
|
||||||
|
width: this.props.coords.width,
|
||||||
|
paddingTop: this.props.coords.paddingTop
|
||||||
|
}}>
|
||||||
|
{
|
||||||
|
this.props.dropDownItems.map(item => {
|
||||||
|
return <React.Fragment key={item.label}>
|
||||||
|
<BoardsDropdownItemComponent isSelected={item.isSelected()} label={item.label} onClick={item.commandExecutor}></BoardsDropdownItemComponent>
|
||||||
|
</React.Fragment>;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
<BoardsDropdownItemComponent isSelected={false} label={'Select Other Board & Port'} onClick={this.props.openDialog}></BoardsDropdownItemComponent>
|
||||||
|
</div>
|
||||||
|
} else {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export namespace BoardsToolBarItem {
|
export namespace BoardsToolBarItem {
|
||||||
export interface Props {
|
export interface Props {
|
||||||
readonly contextMenuRenderer: ContextMenuRenderer;
|
readonly contextMenuRenderer: ContextMenuRenderer;
|
||||||
readonly boardsNotificationService: BoardsNotificationService;
|
readonly boardsNotificationService: BoardsNotificationService;
|
||||||
readonly boardService: BoardsService;
|
readonly boardService: BoardsService;
|
||||||
|
readonly commands: CommandRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface State {
|
export interface State {
|
||||||
selectedBoard?: Board;
|
selectedBoard?: Board;
|
||||||
selectedIsAttached: boolean
|
selectedIsAttached: boolean;
|
||||||
|
boardItems: BoardsDropdownItem[];
|
||||||
|
isOpen: boolean;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class BoardsToolBarItem extends React.Component<BoardsToolBarItem.Props, BoardsToolBarItem.State> {
|
export class BoardsToolBarItem extends React.Component<BoardsToolBarItem.Props, BoardsToolBarItem.State> {
|
||||||
|
|
||||||
protected attachedBoards: Board[];
|
protected attachedBoards: Board[];
|
||||||
|
protected dropDownListCoord: BoardsDropDownListCoord;
|
||||||
|
|
||||||
constructor(props: BoardsToolBarItem.Props) {
|
constructor(props: BoardsToolBarItem.Props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
selectedBoard: undefined,
|
selectedBoard: undefined,
|
||||||
selectedIsAttached: true
|
selectedIsAttached: true,
|
||||||
|
boardItems: [],
|
||||||
|
isOpen: false
|
||||||
};
|
};
|
||||||
|
|
||||||
|
document.addEventListener('click', () => {
|
||||||
|
this.setState({ isOpen: false });
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.setAttachedBoards();
|
this.setAttachedBoards();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async setAttachedBoards() {
|
|
||||||
const { boards } = await this.props.boardService.getAttachedBoards();
|
|
||||||
this.attachedBoards = boards;
|
|
||||||
if (this.attachedBoards.length) {
|
|
||||||
await this.props.boardService.selectBoard(this.attachedBoards[0]);
|
|
||||||
this.setSelectedBoard(this.attachedBoards[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setSelectedBoard(board: Board) {
|
setSelectedBoard(board: Board) {
|
||||||
if (this.attachedBoards && this.attachedBoards.length) {
|
if (this.attachedBoards && this.attachedBoards.length) {
|
||||||
this.setState({ selectedIsAttached: !!this.attachedBoards.find(attachedBoard => attachedBoard.name === board.name) });
|
this.setState({ selectedIsAttached: !!this.attachedBoards.find(attachedBoard => attachedBoard.name === board.name) });
|
||||||
@ -50,31 +137,101 @@ export class BoardsToolBarItem extends React.Component<BoardsToolBarItem.Props,
|
|||||||
this.setState({ selectedBoard: board });
|
this.setState({ selectedBoard: board });
|
||||||
}
|
}
|
||||||
|
|
||||||
protected readonly doShowSelectBoardsMenu = (event: React.MouseEvent<HTMLElement>) => this.showSelectBoardsMenu(event);
|
protected async setAttachedBoards() {
|
||||||
protected showSelectBoardsMenu(event: React.MouseEvent<HTMLElement>) {
|
const { boards } = await this.props.boardService.getAttachedBoards();
|
||||||
const el = (event.target as HTMLElement).parentElement;
|
this.attachedBoards = boards;
|
||||||
if (el) {
|
if (this.attachedBoards.length) {
|
||||||
this.props.contextMenuRenderer.render({
|
await this.createBoardDropdownItems();
|
||||||
menuPath: ArduinoToolbarContextMenu.SELECT_BOARDS_PATH,
|
await this.props.boardService.selectBoard(this.attachedBoards[0]);
|
||||||
anchor: {
|
this.setSelectedBoard(this.attachedBoards[0]);
|
||||||
x: el.getBoundingClientRect().left,
|
}
|
||||||
y: el.getBoundingClientRect().top + el.offsetHeight
|
}
|
||||||
|
|
||||||
|
protected createBoardDropdownItems() {
|
||||||
|
const boardItems: BoardsDropdownItem[] = [];
|
||||||
|
this.attachedBoards.forEach(board => {
|
||||||
|
const { commands } = this.props;
|
||||||
|
const port = this.getPort(board);
|
||||||
|
const command: Command = {
|
||||||
|
id: 'selectBoard' + port
|
||||||
|
}
|
||||||
|
commands.registerCommand(command, {
|
||||||
|
execute: () => {
|
||||||
|
commands.executeCommand(ArduinoCommands.SELECT_BOARD.id, board);
|
||||||
|
this.setState({ isOpen: false, selectedBoard: board });
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
boardItems.push({
|
||||||
|
commandExecutor: () => commands.executeCommand(command.id),
|
||||||
|
label: board.name + ' at ' + port,
|
||||||
|
isSelected: () => this.doIsSelectedBoard(board)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
this.setState({ boardItems });
|
||||||
|
}
|
||||||
|
|
||||||
|
protected doIsSelectedBoard = (board: Board) => this.isSelectedBoard(board);
|
||||||
|
protected isSelectedBoard(board: Board): boolean {
|
||||||
|
return AttachedSerialBoard.is(board) &&
|
||||||
|
!!this.state.selectedBoard &&
|
||||||
|
AttachedSerialBoard.is(this.state.selectedBoard) &&
|
||||||
|
board.port === this.state.selectedBoard.port &&
|
||||||
|
board.fqbn === this.state.selectedBoard.fqbn;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected getPort(board: Board): string {
|
||||||
|
if (AttachedSerialBoard.is(board)) {
|
||||||
|
return board.port;
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
protected readonly doShowSelectBoardsMenu = (event: React.MouseEvent<HTMLElement>) => {
|
||||||
|
this.showSelectBoardsMenu(event);
|
||||||
|
event.stopPropagation();
|
||||||
|
event.nativeEvent.stopImmediatePropagation();
|
||||||
|
};
|
||||||
|
protected showSelectBoardsMenu(event: React.MouseEvent<HTMLElement>) {
|
||||||
|
const el = (event.currentTarget as HTMLElement);
|
||||||
|
if (el) {
|
||||||
|
this.dropDownListCoord = {
|
||||||
|
top: el.getBoundingClientRect().top,
|
||||||
|
left: el.getBoundingClientRect().left,
|
||||||
|
paddingTop: el.getBoundingClientRect().height,
|
||||||
|
width: el.getBoundingClientRect().width
|
||||||
|
}
|
||||||
|
this.setState({ isOpen: !this.state.isOpen });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render(): React.ReactNode {
|
render(): React.ReactNode {
|
||||||
|
const selectedBoard = this.state.selectedBoard;
|
||||||
|
const port = selectedBoard ? this.getPort(selectedBoard) : undefined;
|
||||||
return <React.Fragment>
|
return <React.Fragment>
|
||||||
<div className='arduino-boards-toolbar-item-container' onClick={this.doShowSelectBoardsMenu}>
|
<div className='arduino-boards-toolbar-item-container'>
|
||||||
<div className='arduino-boards-toolbar-item'>
|
<div className='arduino-boards-toolbar-item' title={selectedBoard && `${selectedBoard.name}${port ? ' at ' + port : ''}`}>
|
||||||
<div className='inner-container'>
|
<div className='inner-container' onClick={this.doShowSelectBoardsMenu}>
|
||||||
<span className={!this.state.selectedBoard || !this.state.selectedIsAttached ? 'fa fa-times notAttached' : ''}></span>
|
<span className={!selectedBoard || !this.state.selectedIsAttached ? 'fa fa-times notAttached' : ''}></span>
|
||||||
<div className='label'>{this.state.selectedBoard ? this.state.selectedBoard.name : 'no board selected'}</div>
|
<div className='label noWrapInfo'>
|
||||||
<span className='fa fa-caret-down'></span>
|
<div className='noWrapInfo'>
|
||||||
|
{selectedBoard ? `${selectedBoard.name}${port ? ' at ' + port : ''}` : 'no board selected'}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span className='fa fa-caret-down caret'></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<BoardsDropDown
|
||||||
|
isOpen={this.state.isOpen}
|
||||||
|
coords={this.dropDownListCoord}
|
||||||
|
dropDownItems={this.state.boardItems}
|
||||||
|
openDialog={this.openDialog}>
|
||||||
|
</BoardsDropDown>
|
||||||
</React.Fragment>;
|
</React.Fragment>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected openDialog = () => {
|
||||||
|
this.props.commands.executeCommand(ArduinoCommands.OPEN_BOARDS_DIALOG.id);
|
||||||
|
this.setState({ isOpen: false });
|
||||||
|
};
|
||||||
}
|
}
|
@ -123,30 +123,62 @@ button.theia-button.main {
|
|||||||
.arduino-boards-toolbar-item-container .arduino-boards-toolbar-item .inner-container {
|
.arduino-boards-toolbar-item-container .arduino-boards-toolbar-item .inner-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: baseline;
|
align-items: baseline;
|
||||||
margin: 0 5px;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.arduino-boards-toolbar-item-container .arduino-boards-toolbar-item .inner-container .notAttached {
|
.arduino-boards-toolbar-item-container .arduino-boards-toolbar-item .inner-container .notAttached {
|
||||||
width: 10px;
|
width: 10px;
|
||||||
height: 10px;
|
height: 10px;
|
||||||
color: red;
|
color: red;
|
||||||
margin-right: 5px;
|
margin: 0 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.arduino-boards-toolbar-item-container {
|
.arduino-boards-toolbar-item-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
width: 220px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.arduino-boards-toolbar-item .label {
|
.arduino-boards-toolbar-item .label {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
margin: 0 5px;
|
||||||
|
width: 100%;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arduino-boards-toolbar-item .caret {
|
||||||
|
width: 10px;
|
||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.arduino-boards-toolbar-item {
|
.arduino-boards-toolbar-item {
|
||||||
background: white;
|
background: white;
|
||||||
height: 18px;
|
height: 22px;
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.arduino-boards-dropdown-list {
|
||||||
|
background: #f7f7f7;
|
||||||
|
border: 3px solid var(--theia-border-color2);
|
||||||
|
margin: -3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arduino-boards-dropdown-item {
|
||||||
|
font-size: var(--theia-ui-font-size1);
|
||||||
|
display: flex;
|
||||||
|
padding: 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arduino-boards-dropdown-item .fa-check {
|
||||||
|
color: var(--theia-accent-color2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.arduino-boards-dropdown-item.selected,
|
||||||
|
.arduino-boards-dropdown-item:hover {
|
||||||
|
background: var(--theia-ui-button-color-secondary-hover);
|
||||||
|
}
|
@ -61,21 +61,6 @@
|
|||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.arduino-boards-toolbar-item-container {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.arduino-boards-toolbar-item .label {
|
|
||||||
height: 100%;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.arduino-boards-toolbar-item {
|
|
||||||
background: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.arduino-tool-item.item.connected-boards select {
|
.arduino-tool-item.item.connected-boards select {
|
||||||
line-height: var(--theia-content-line-height);
|
line-height: var(--theia-content-line-height);
|
||||||
font-size: var(--theia-ui-font-size1);
|
font-size: var(--theia-ui-font-size1);
|
||||||
@ -105,3 +90,9 @@
|
|||||||
border-right: 2px solid var(--theia-border-color1);
|
border-right: 2px solid var(--theia-border-color1);
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.noWrapInfo {
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user