From 56fb68fa8e23cf5a0124d912b9237e3e3328b19c Mon Sep 17 00:00:00 2001 From: Francesco Stasi Date: Tue, 9 Mar 2021 14:47:41 +0100 Subject: [PATCH] Support toggled state in arduino toolbar items fix hover state on toolbar items Improved statemanagement for ToolbarItem and Menus Disable Upload buttons while a sketch upload is already in progress toggled state to have override disabled button opacity doublecheck internal status before verify/upload a sketch fixes after code review --- .../browser/arduino-frontend-contribution.tsx | 13 ++++++-- .../browser/contributions/upload-sketch.ts | 30 ++++++++++++++++-- .../browser/contributions/verify-sketch.ts | 31 +++++++++++++++++-- .../src/browser/style/main.css | 14 +++++++-- .../src/browser/toolbar/arduino-toolbar.tsx | 8 ++++- 5 files changed, 85 insertions(+), 11 deletions(-) diff --git a/arduino-ide-extension/src/browser/arduino-frontend-contribution.tsx b/arduino-ide-extension/src/browser/arduino-frontend-contribution.tsx index 092834fca..612f7ea63 100644 --- a/arduino-ide-extension/src/browser/arduino-frontend-contribution.tsx +++ b/arduino-ide-extension/src/browser/arduino-frontend-contribution.tsx @@ -413,11 +413,20 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut id: 'arduino.toolbar.hoverBackground', defaults: { dark: 'button.hoverBackground', - light: 'button.hoverBackground', - hc: 'activityBar.inactiveForeground' + light: 'button.foreground', + hc: 'textLink.foreground' }, description: 'Background color of the toolbar items when hovering over them. Such as Upload, Verify, etc.' }, + { + id: 'arduino.toolbar.toggleBackground', + defaults: { + dark: 'editor.selectionBackground', + light: 'editor.selectionBackground', + hc: 'textPreformat.foreground' + }, + description: 'Toggle color of the toolbar items when they are currently toggled (the command is in progress)' + }, { id: 'arduino.output.foreground', defaults: { diff --git a/arduino-ide-extension/src/browser/contributions/upload-sketch.ts b/arduino-ide-extension/src/browser/contributions/upload-sketch.ts index 4f0109aa8..c06dece19 100644 --- a/arduino-ide-extension/src/browser/contributions/upload-sketch.ts +++ b/arduino-ide-extension/src/browser/contributions/upload-sketch.ts @@ -1,4 +1,5 @@ import { inject, injectable } from 'inversify'; +import { Emitter } from '@theia/core/lib/common/event'; import { CoreService } from '../../common/protocol'; import { ArduinoMenus } from '../menu/arduino-menus'; import { ArduinoToolbar } from '../toolbar/arduino-toolbar'; @@ -22,15 +23,24 @@ export class UploadSketch extends SketchContribution { @inject(BoardsServiceProvider) protected readonly boardsServiceClientImpl: BoardsServiceProvider; + protected readonly onDidChangeEmitter = new Emitter>(); + readonly onDidChange = this.onDidChangeEmitter.event; + + protected uploadInProgress = false; + registerCommands(registry: CommandRegistry): void { registry.registerCommand(UploadSketch.Commands.UPLOAD_SKETCH, { - execute: () => this.uploadSketch() + execute: () => this.uploadSketch(), + isEnabled: () => !this.uploadInProgress, }); registry.registerCommand(UploadSketch.Commands.UPLOAD_SKETCH_USING_PROGRAMMER, { - execute: () => this.uploadSketch(true) + execute: () => this.uploadSketch(true), + isEnabled: () => !this.uploadInProgress, }); registry.registerCommand(UploadSketch.Commands.UPLOAD_SKETCH_TOOLBAR, { isVisible: widget => ArduinoToolbar.is(widget) && widget.side === 'left', + isEnabled: () => !this.uploadInProgress, + isToggled: () => this.uploadInProgress, execute: () => registry.executeCommand(UploadSketch.Commands.UPLOAD_SKETCH.id) }); } @@ -64,11 +74,22 @@ export class UploadSketch extends SketchContribution { id: UploadSketch.Commands.UPLOAD_SKETCH_TOOLBAR.id, command: UploadSketch.Commands.UPLOAD_SKETCH_TOOLBAR.id, tooltip: 'Upload', - priority: 1 + priority: 1, + onDidChange: this.onDidChange }); } async uploadSketch(usingProgrammer: boolean = false): Promise { + + // even with buttons disabled, better to double check if an upload is already in progress + if (this.uploadInProgress) { + return; + } + + // toggle the toolbar button and menu item state. + // uploadInProgress will be set to false whether the upload fails or not + this.uploadInProgress = true; + this.onDidChangeEmitter.fire(); const sketch = await this.sketchServiceClient.currentSketch(); if (!sketch) { return; @@ -131,6 +152,9 @@ export class UploadSketch extends SketchContribution { } catch (e) { this.messageService.error(e.toString()); } finally { + this.uploadInProgress = false; + this.onDidChangeEmitter.fire(); + if (monitorConfig) { const { board, port } = monitorConfig; try { diff --git a/arduino-ide-extension/src/browser/contributions/verify-sketch.ts b/arduino-ide-extension/src/browser/contributions/verify-sketch.ts index fe9b3e074..225d1281c 100644 --- a/arduino-ide-extension/src/browser/contributions/verify-sketch.ts +++ b/arduino-ide-extension/src/browser/contributions/verify-sketch.ts @@ -1,4 +1,5 @@ import { inject, injectable } from 'inversify'; +import { Emitter } from '@theia/core/lib/common/event'; import { CoreService } from '../../common/protocol'; import { ArduinoMenus } from '../menu/arduino-menus'; import { ArduinoToolbar } from '../toolbar/arduino-toolbar'; @@ -18,15 +19,24 @@ export class VerifySketch extends SketchContribution { @inject(BoardsServiceProvider) protected readonly boardsServiceClientImpl: BoardsServiceProvider; + protected readonly onDidChangeEmitter = new Emitter>(); + readonly onDidChange = this.onDidChangeEmitter.event; + + protected verifyInProgress = false; + registerCommands(registry: CommandRegistry): void { registry.registerCommand(VerifySketch.Commands.VERIFY_SKETCH, { - execute: () => this.verifySketch() + execute: () => this.verifySketch(), + isEnabled: () => !this.verifyInProgress, }); registry.registerCommand(VerifySketch.Commands.EXPORT_BINARIES, { - execute: () => this.verifySketch(true) + execute: () => this.verifySketch(true), + isEnabled: () => !this.verifyInProgress, }); registry.registerCommand(VerifySketch.Commands.VERIFY_SKETCH_TOOLBAR, { isVisible: widget => ArduinoToolbar.is(widget) && widget.side === 'left', + isEnabled: () => !this.verifyInProgress, + isToggled: () => this.verifyInProgress, execute: () => registry.executeCommand(VerifySketch.Commands.VERIFY_SKETCH.id) }); } @@ -60,12 +70,24 @@ export class VerifySketch extends SketchContribution { id: VerifySketch.Commands.VERIFY_SKETCH_TOOLBAR.id, command: VerifySketch.Commands.VERIFY_SKETCH_TOOLBAR.id, tooltip: 'Verify', - priority: 0 + priority: 0, + onDidChange: this.onDidChange }); } async verifySketch(exportBinaries?: boolean): Promise { + + // even with buttons disabled, better to double check if a verify is already in progress + if (this.verifyInProgress) { + return; + } + + // toggle the toolbar button and menu item state. + // verifyInProgress will be set to false whether the compilation fails or not + this.verifyInProgress = true; + this.onDidChangeEmitter.fire(); const sketch = await this.sketchServiceClient.currentSketch(); + if (!sketch) { return; } @@ -90,6 +112,9 @@ export class VerifySketch extends SketchContribution { this.messageService.info('Done compiling.', { timeout: 1000 }); } catch (e) { this.messageService.error(e.toString()); + } finally { + this.verifyInProgress = false; + this.onDidChangeEmitter.fire(); } } diff --git a/arduino-ide-extension/src/browser/style/main.css b/arduino-ide-extension/src/browser/style/main.css index 8bb9d1253..1bdfd4626 100644 --- a/arduino-ide-extension/src/browser/style/main.css +++ b/arduino-ide-extension/src/browser/style/main.css @@ -15,8 +15,8 @@ background: var(--theia-arduino-toolbar-background); } -.p-TabBar-toolbar .item.arduino-tool-item > div:hover { - background: (--theia-arduino-toolbar-hoverBackground); +.p-TabBar-toolbar .item.arduino-tool-item.enabled:hover > div { + background: var(--theia-arduino-toolbar-hoverBackground); } .arduino-verify-sketch--toolbar, @@ -24,6 +24,16 @@ border-radius: 12px; } +.item.arduino-tool-item.toggled { + background-color: unset; + opacity: 1; + border: none; +} + +.item.arduino-tool-item.toggled .arduino-verify-sketch--toolbar { + background-color: var(--theia-arduino-toolbar-toggleBackground) !important; +} + .arduino-tool-icon { height: 24px; width: 24px; diff --git a/arduino-ide-extension/src/browser/toolbar/arduino-toolbar.tsx b/arduino-ide-extension/src/browser/toolbar/arduino-toolbar.tsx index f9b6b5ab0..91ea3f131 100644 --- a/arduino-ide-extension/src/browser/toolbar/arduino-toolbar.tsx +++ b/arduino-ide-extension/src/browser/toolbar/arduino-toolbar.tsx @@ -13,6 +13,7 @@ export namespace ArduinoToolbarComponent { commands: CommandRegistry, labelParser: LabelParser, commandIsEnabled: (id: string) => boolean, + commandIsToggled: (id: string) => boolean, executeCommand: (e: React.MouseEvent) => void } export interface State { @@ -39,7 +40,7 @@ export class ArduinoToolbarComponent extends React.Component
this.commandIsToggled(id); + protected commandIsToggled(command: string): boolean { + return this.commands.isToggled(command, this); + } protected render(): React.ReactNode { return }