Skip to content

Commit 1e0f52b

Browse files
committed
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
1 parent 6dadd17 commit 1e0f52b

File tree

5 files changed

+85
-11
lines changed

5 files changed

+85
-11
lines changed

Diff for: arduino-ide-extension/src/browser/arduino-frontend-contribution.tsx

+11-2
Original file line numberDiff line numberDiff line change
@@ -414,11 +414,20 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut
414414
id: 'arduino.toolbar.hoverBackground',
415415
defaults: {
416416
dark: 'button.hoverBackground',
417-
light: 'button.hoverBackground',
418-
hc: 'activityBar.inactiveForeground'
417+
light: 'button.foreground',
418+
hc: 'textLink.foreground'
419419
},
420420
description: 'Background color of the toolbar items when hovering over them. Such as Upload, Verify, etc.'
421421
},
422+
{
423+
id: 'arduino.toolbar.toggleBackground',
424+
defaults: {
425+
dark: 'editor.selectionBackground',
426+
light: 'editor.selectionBackground',
427+
hc: 'textPreformat.foreground'
428+
},
429+
description: 'Toggle color of the toolbar items when they are currently toggled (the command is in progress)'
430+
},
422431
{
423432
id: 'arduino.output.foreground',
424433
defaults: {

Diff for: arduino-ide-extension/src/browser/contributions/upload-sketch.ts

+27-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { inject, injectable } from 'inversify';
2+
import { Emitter } from '@theia/core/lib/common/event';
23
import { CoreService } from '../../common/protocol';
34
import { ArduinoMenus } from '../menu/arduino-menus';
45
import { ArduinoToolbar } from '../toolbar/arduino-toolbar';
@@ -22,15 +23,24 @@ export class UploadSketch extends SketchContribution {
2223
@inject(BoardsServiceProvider)
2324
protected readonly boardsServiceClientImpl: BoardsServiceProvider;
2425

26+
protected readonly onDidChangeEmitter = new Emitter<Readonly<void>>();
27+
readonly onDidChange = this.onDidChangeEmitter.event;
28+
29+
protected uploadInProgress = false;
30+
2531
registerCommands(registry: CommandRegistry): void {
2632
registry.registerCommand(UploadSketch.Commands.UPLOAD_SKETCH, {
27-
execute: () => this.uploadSketch()
33+
execute: () => this.uploadSketch(),
34+
isEnabled: () => !this.uploadInProgress,
2835
});
2936
registry.registerCommand(UploadSketch.Commands.UPLOAD_SKETCH_USING_PROGRAMMER, {
30-
execute: () => this.uploadSketch(true)
37+
execute: () => this.uploadSketch(true),
38+
isEnabled: () => !this.uploadInProgress,
3139
});
3240
registry.registerCommand(UploadSketch.Commands.UPLOAD_SKETCH_TOOLBAR, {
3341
isVisible: widget => ArduinoToolbar.is(widget) && widget.side === 'left',
42+
isEnabled: () => !this.uploadInProgress,
43+
isToggled: () => this.uploadInProgress,
3444
execute: () => registry.executeCommand(UploadSketch.Commands.UPLOAD_SKETCH.id)
3545
});
3646
}
@@ -64,11 +74,22 @@ export class UploadSketch extends SketchContribution {
6474
id: UploadSketch.Commands.UPLOAD_SKETCH_TOOLBAR.id,
6575
command: UploadSketch.Commands.UPLOAD_SKETCH_TOOLBAR.id,
6676
tooltip: 'Upload',
67-
priority: 1
77+
priority: 1,
78+
onDidChange: this.onDidChange
6879
});
6980
}
7081

7182
async uploadSketch(usingProgrammer: boolean = false): Promise<void> {
83+
84+
// even with buttons disabled, better to double check if an upload is already in progress
85+
if (this.uploadInProgress) {
86+
return;
87+
}
88+
89+
// toggle the toolbar button and menu item state.
90+
// uploadInProgress will be set to false whether the upload fails or not
91+
this.uploadInProgress = true;
92+
this.onDidChangeEmitter.fire();
7293
const sketch = await this.sketchServiceClient.currentSketch();
7394
if (!sketch) {
7495
return;
@@ -131,6 +152,9 @@ export class UploadSketch extends SketchContribution {
131152
} catch (e) {
132153
this.messageService.error(e.toString());
133154
} finally {
155+
this.uploadInProgress = false;
156+
this.onDidChangeEmitter.fire();
157+
134158
if (monitorConfig) {
135159
const { board, port } = monitorConfig;
136160
try {

Diff for: arduino-ide-extension/src/browser/contributions/verify-sketch.ts

+28-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { inject, injectable } from 'inversify';
2+
import { Emitter } from '@theia/core/lib/common/event';
23
import { CoreService } from '../../common/protocol';
34
import { ArduinoMenus } from '../menu/arduino-menus';
45
import { ArduinoToolbar } from '../toolbar/arduino-toolbar';
@@ -18,15 +19,24 @@ export class VerifySketch extends SketchContribution {
1819
@inject(BoardsServiceProvider)
1920
protected readonly boardsServiceClientImpl: BoardsServiceProvider;
2021

22+
protected readonly onDidChangeEmitter = new Emitter<Readonly<void>>();
23+
readonly onDidChange = this.onDidChangeEmitter.event;
24+
25+
protected verifyInProgress = false;
26+
2127
registerCommands(registry: CommandRegistry): void {
2228
registry.registerCommand(VerifySketch.Commands.VERIFY_SKETCH, {
23-
execute: () => this.verifySketch()
29+
execute: () => this.verifySketch(),
30+
isEnabled: () => !this.verifyInProgress,
2431
});
2532
registry.registerCommand(VerifySketch.Commands.EXPORT_BINARIES, {
26-
execute: () => this.verifySketch(true)
33+
execute: () => this.verifySketch(true),
34+
isEnabled: () => !this.verifyInProgress,
2735
});
2836
registry.registerCommand(VerifySketch.Commands.VERIFY_SKETCH_TOOLBAR, {
2937
isVisible: widget => ArduinoToolbar.is(widget) && widget.side === 'left',
38+
isEnabled: () => !this.verifyInProgress,
39+
isToggled: () => this.verifyInProgress,
3040
execute: () => registry.executeCommand(VerifySketch.Commands.VERIFY_SKETCH.id)
3141
});
3242
}
@@ -60,12 +70,24 @@ export class VerifySketch extends SketchContribution {
6070
id: VerifySketch.Commands.VERIFY_SKETCH_TOOLBAR.id,
6171
command: VerifySketch.Commands.VERIFY_SKETCH_TOOLBAR.id,
6272
tooltip: 'Verify',
63-
priority: 0
73+
priority: 0,
74+
onDidChange: this.onDidChange
6475
});
6576
}
6677

6778
async verifySketch(exportBinaries?: boolean): Promise<void> {
79+
80+
// even with buttons disabled, better to double check if a verify is already in progress
81+
if (this.verifyInProgress) {
82+
return;
83+
}
84+
85+
// toggle the toolbar button and menu item state.
86+
// verifyInProgress will be set to false whether the compilation fails or not
87+
this.verifyInProgress = true;
88+
this.onDidChangeEmitter.fire();
6889
const sketch = await this.sketchServiceClient.currentSketch();
90+
6991
if (!sketch) {
7092
return;
7193
}
@@ -90,6 +112,9 @@ export class VerifySketch extends SketchContribution {
90112
this.messageService.info('Done compiling.', { timeout: 1000 });
91113
} catch (e) {
92114
this.messageService.error(e.toString());
115+
} finally {
116+
this.verifyInProgress = false;
117+
this.onDidChangeEmitter.fire();
93118
}
94119
}
95120

Diff for: arduino-ide-extension/src/browser/style/main.css

+12-2
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,25 @@
1515
background: var(--theia-arduino-toolbar-background);
1616
}
1717

18-
.p-TabBar-toolbar .item.arduino-tool-item > div:hover {
19-
background: (--theia-arduino-toolbar-hoverBackground);
18+
.p-TabBar-toolbar .item.arduino-tool-item.enabled:hover > div {
19+
background: var(--theia-arduino-toolbar-hoverBackground);
2020
}
2121

2222
.arduino-verify-sketch--toolbar,
2323
.arduino-upload-sketch--toolbar {
2424
border-radius: 12px;
2525
}
2626

27+
.item.arduino-tool-item.toggled {
28+
background-color: unset;
29+
opacity: 1;
30+
border: none;
31+
}
32+
33+
.item.arduino-tool-item.toggled .arduino-verify-sketch--toolbar {
34+
background-color: var(--theia-arduino-toolbar-toggleBackground) !important;
35+
}
36+
2737
.arduino-tool-icon {
2838
height: 24px;
2939
width: 24px;

Diff for: arduino-ide-extension/src/browser/toolbar/arduino-toolbar.tsx

+7-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export namespace ArduinoToolbarComponent {
1313
commands: CommandRegistry,
1414
labelParser: LabelParser,
1515
commandIsEnabled: (id: string) => boolean,
16+
commandIsToggled: (id: string) => boolean,
1617
executeCommand: (e: React.MouseEvent<HTMLElement>) => void
1718
}
1819
export interface State {
@@ -39,7 +40,7 @@ export class ArduinoToolbarComponent extends React.Component<ArduinoToolbarCompo
3940
}
4041
}
4142
const command = this.props.commands.getCommand(item.command);
42-
const cls = `${ARDUINO_TOOLBAR_ITEM_CLASS} ${TabBarToolbar.Styles.TAB_BAR_TOOLBAR_ITEM} ${command && this.props.commandIsEnabled(command.id) ? 'enabled' : ''}`
43+
const cls = `${ARDUINO_TOOLBAR_ITEM_CLASS} ${TabBarToolbar.Styles.TAB_BAR_TOOLBAR_ITEM} ${command && this.props.commandIsEnabled(command.id) ? 'enabled' : ''} ${command && this.props.commandIsToggled(command.id) ? 'toggled' : ''}`
4344
return <div key={item.id} className={cls} >
4445
<div className={item.id}>
4546
<div
@@ -112,6 +113,10 @@ export class ArduinoToolbar extends ReactWidget {
112113
protected commandIsEnabled(command: string): boolean {
113114
return this.commands.isEnabled(command, this);
114115
}
116+
protected readonly doCommandIsToggled = (id: string) => this.commandIsToggled(id);
117+
protected commandIsToggled(command: string): boolean {
118+
return this.commands.isToggled(command, this);
119+
}
115120

116121
protected render(): React.ReactNode {
117122
return <ArduinoToolbarComponent
@@ -121,6 +126,7 @@ export class ArduinoToolbar extends ReactWidget {
121126
items={[...this.items.values()]}
122127
commands={this.commands}
123128
commandIsEnabled={this.doCommandIsEnabled}
129+
commandIsToggled={this.doCommandIsToggled}
124130
executeCommand={this.executeCommand}
125131
/>
126132
}

0 commit comments

Comments
 (0)