Skip to content

Commit dd69092

Browse files
committed
Added additional toolbar to the right of the toppanel.
Added Toolbar button for toggling serial monitor and tooltips for serial monitor toolbar items. Signed-off-by: jbicker <jan.bicker@typefox.io>
1 parent 76d0f5a commit dd69092

File tree

5 files changed

+100
-41
lines changed

5 files changed

+100
-41
lines changed

arduino-ide-extension/src/browser/arduino-frontend-contribution.tsx

+14-14
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ import { BoardsConfig } from './boards/boards-config';
4848
import { MonitorService } from '../common/protocol/monitor-service';
4949
import { ConfigService } from '../common/protocol/config-service';
5050
import { MonitorConnection } from './monitor/monitor-connection';
51+
import { MonitorViewContribution } from './monitor/monitor-view-contribution';
5152

5253
export namespace ArduinoMenus {
5354
export const SKETCH = [...MAIN_MENU_BAR, '3_sketch'];
@@ -200,13 +201,19 @@ export class ArduinoFrontendContribution implements TabBarToolbarContribution, C
200201
commands={this.commands}
201202
boardsServiceClient={this.boardsServiceClient}
202203
boardService={this.boardsService} />,
203-
isVisible: widget => this.isArduinoToolbar(widget)
204+
isVisible: widget => ArduinoToolbar.is(widget) && widget.side === 'left'
205+
});
206+
registry.registerItem({
207+
id: 'toggle-serial-monitor',
208+
command: MonitorViewContribution.OPEN_SERIAL_MONITOR,
209+
tooltip: 'Toggle Serial Monitor',
210+
isVisible: widget => ArduinoToolbar.is(widget) && widget.side === 'right'
204211
})
205212
}
206213

207214
registerCommands(registry: CommandRegistry): void {
208215
registry.registerCommand(ArduinoCommands.VERIFY, {
209-
isVisible: widget => this.isArduinoToolbar(widget),
216+
isVisible: widget => ArduinoToolbar.is(widget) && widget.side === 'left',
210217
isEnabled: widget => true,
211218
execute: async () => {
212219
const widget = this.getCurrentWidget();
@@ -234,7 +241,7 @@ export class ArduinoFrontendContribution implements TabBarToolbarContribution, C
234241
}
235242
});
236243
registry.registerCommand(ArduinoCommands.UPLOAD, {
237-
isVisible: widget => this.isArduinoToolbar(widget),
244+
isVisible: widget => ArduinoToolbar.is(widget) && widget.side === 'left',
238245
isEnabled: widget => true,
239246
execute: async () => {
240247
const widget = this.getCurrentWidget();
@@ -270,8 +277,8 @@ export class ArduinoFrontendContribution implements TabBarToolbarContribution, C
270277
}
271278
});
272279
registry.registerCommand(ArduinoCommands.SHOW_OPEN_CONTEXT_MENU, {
273-
isVisible: widget => this.isArduinoToolbar(widget),
274-
isEnabled: widget => this.isArduinoToolbar(widget),
280+
isVisible: widget => ArduinoToolbar.is(widget) && widget.side === 'left',
281+
isEnabled: widget => ArduinoToolbar.is(widget) && widget.side === 'left',
275282
execute: async (widget: Widget, target: EventTarget) => {
276283
if (this.wsSketchCount) {
277284
const el = (target as HTMLElement).parentElement;
@@ -297,8 +304,8 @@ export class ArduinoFrontendContribution implements TabBarToolbarContribution, C
297304
}
298305
})
299306
registry.registerCommand(ArduinoCommands.SAVE_SKETCH, {
300-
isEnabled: widget => this.isArduinoToolbar(widget),
301-
isVisible: widget => this.isArduinoToolbar(widget),
307+
isEnabled: widget => ArduinoToolbar.is(widget) && widget.side === 'left',
308+
isVisible: widget => ArduinoToolbar.is(widget) && widget.side === 'left',
302309
execute: async (sketch: Sketch) => {
303310
registry.executeCommand(CommonCommands.SAVE_ALL.id);
304311
}
@@ -565,13 +572,6 @@ export class ArduinoFrontendContribution implements TabBarToolbarContribution, C
565572
return undefined;
566573
}
567574

568-
private isArduinoToolbar(maybeToolbarWidget: any): boolean {
569-
if (maybeToolbarWidget instanceof ArduinoToolbar) {
570-
return true;
571-
}
572-
return false;
573-
}
574-
575575
private toUri(arg: any): URI | undefined {
576576
if (arg instanceof URI) {
577577
return arg;

arduino-ide-extension/src/browser/monitor/monitor-view-contribution.tsx

+12-5
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { MenuModelRegistry, Command, CommandRegistry } from "@theia/core";
66
import { ArduinoMenus } from "../arduino-frontend-contribution";
77
import { TabBarToolbarContribution, TabBarToolbarRegistry } from "@theia/core/lib/browser/shell/tab-bar-toolbar";
88
import { MonitorModel } from './monitor-model';
9+
import { ArduinoToolbar } from '../toolbar/arduino-toolbar';
910

1011
export namespace SerialMonitor {
1112
export namespace Commands {
@@ -56,14 +57,12 @@ export class MonitorViewContribution extends AbstractViewContribution<MonitorWid
5657
async registerToolbarItems(registry: TabBarToolbarRegistry) {
5758
registry.registerItem({
5859
id: 'monitor-autoscroll',
59-
tooltip: 'Toggle Autoscroll',
6060
render: () => this.renderAutoScrollButton(),
6161
isVisible: widget => widget instanceof MonitorWidget,
6262
onDidChange: this.model.onChange
6363
});
6464
registry.registerItem({
6565
id: 'monitor-timestamp',
66-
tooltip: 'Toggle Timestamp',
6766
render: () => this.renderTimestampButton(),
6867
isVisible: widget => widget instanceof MonitorWidget,
6968
onDidChange: this.model.onChange
@@ -76,7 +75,6 @@ export class MonitorViewContribution extends AbstractViewContribution<MonitorWid
7675
}
7776

7877
registerCommands(commands: CommandRegistry): void {
79-
super.registerCommands(commands);
8078
commands.registerCommand(SerialMonitor.Commands.CLEAR_OUTPUT, {
8179
isEnabled: widget => widget instanceof MonitorWidget,
8280
isVisible: widget => widget instanceof MonitorWidget,
@@ -86,12 +84,21 @@ export class MonitorViewContribution extends AbstractViewContribution<MonitorWid
8684
}
8785
}
8886
});
87+
if (this.toggleCommand) {
88+
commands.registerCommand(this.toggleCommand, {
89+
execute: () => this.openView({
90+
toggle: true,
91+
activate: true
92+
}),
93+
isVisible: widget => ArduinoToolbar.is(widget) && widget.side === 'right'
94+
});
95+
}
8996
}
9097

9198
protected renderAutoScrollButton(): React.ReactNode {
92-
9399
return <React.Fragment>
94100
<div
101+
title='Toggle Autoscroll'
95102
className={`item enabled fa fa-angle-double-down arduino-monitor ${this.model.autoscroll ? 'toggled' : ''}`}
96103
onClick={this.toggleAutoScroll}
97104
></div>
@@ -104,9 +111,9 @@ export class MonitorViewContribution extends AbstractViewContribution<MonitorWid
104111
}
105112

106113
protected renderTimestampButton(): React.ReactNode {
107-
108114
return <React.Fragment>
109115
<div
116+
title='Toggle Timestamp'
110117
className={`item enabled fa fa-clock-o arduino-monitor ${this.model.timestamp ? 'toggled' : ''}`}
111118
onClick={this.toggleTimestamp}
112119
></div>

arduino-ide-extension/src/browser/style/main.css

+21
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,15 @@
1111
cursor: text;
1212
}
1313

14+
#toggle-serial-monitor.arduino-tool-icon:hover,
1415
#arduino-verify.arduino-tool-icon:hover,
1516
#arduino-save-file.arduino-tool-icon:hover,
1617
#arduino-show-open-context-menu.arduino-tool-icon:hover,
1718
#arduino-upload.arduino-tool-icon:hover {
1819
background-position-y: 60px;
1920
}
2021

22+
#toggle-serial-monitor.arduino-tool-icon,
2123
#arduino-verify.arduino-tool-icon,
2224
#arduino-save-file.arduino-tool-icon,
2325
#arduino-show-open-context-menu.arduino-tool-icon,
@@ -54,10 +56,29 @@
5456
background-position-x: 92px;
5557
}
5658

59+
#toggle-serial-monitor {
60+
background: url(../icons/buttons.svg);
61+
background-size: 800%;
62+
background-position-y: 28px;
63+
background-position-x: 28px;
64+
}
65+
5766
.p-TabBar-toolbar .item.arduino-tool-item {
5867
margin-left: 3px;
5968
}
6069

70+
#arduino-toolbar-container {
71+
display: flex;
72+
}
73+
74+
.p-TabBar-toolbar.theia-arduino-toolbar {
75+
flex: 1;
76+
}
77+
78+
#theia-top-panel .p-TabBar-toolbar.theia-arduino-toolbar.right {
79+
justify-content: flex-start;
80+
}
81+
6182
.arduino-tool-item.item.connected-boards {
6283
opacity: 1;
6384
}
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,40 @@
1-
import { FrontendApplicationContribution, FrontendApplication } from "@theia/core/lib/browser";
1+
import { FrontendApplicationContribution, FrontendApplication, Widget, Message } from "@theia/core/lib/browser";
22
import { injectable, inject } from "inversify";
33
import { ArduinoToolbar } from "./arduino-toolbar";
44
import { TabBarToolbarRegistry } from "@theia/core/lib/browser/shell/tab-bar-toolbar";
55
import { CommandRegistry } from "@theia/core";
66
import { LabelParser } from "@theia/core/lib/browser/label-parser";
77

8+
export class ArduinoToolbarContainer extends Widget {
9+
constructor(protected left: ArduinoToolbar, protected right: ArduinoToolbar) {
10+
super();
11+
this.id = 'arduino-toolbar-container';
12+
}
13+
14+
onAfterAttach(msg: Message) {
15+
Widget.attach(this.left, this.node);
16+
Widget.attach(this.right, this.node);
17+
}
18+
}
19+
820
@injectable()
921
export class ArduinoToolbarContribution implements FrontendApplicationContribution {
1022

11-
protected toolbarWidget: ArduinoToolbar;
23+
protected arduinoToolbarContainer: ArduinoToolbarContainer;
1224

1325
constructor(
1426
@inject(TabBarToolbarRegistry) protected tabBarToolBarRegistry: TabBarToolbarRegistry,
1527
@inject(CommandRegistry) protected commandRegistry: CommandRegistry,
1628
@inject(LabelParser) protected labelParser: LabelParser) {
17-
this.toolbarWidget = new ArduinoToolbar(tabBarToolBarRegistry, commandRegistry, labelParser);
29+
const leftToolbarWidget = new ArduinoToolbar(tabBarToolBarRegistry, commandRegistry, labelParser, 'left');
30+
const rightToolbarWidget = new ArduinoToolbar(tabBarToolBarRegistry, commandRegistry, labelParser, 'right');
31+
this.arduinoToolbarContainer = new ArduinoToolbarContainer(leftToolbarWidget, rightToolbarWidget);
1832
}
1933

2034

2135
onStart(app: FrontendApplication) {
22-
app.shell.addWidget(this.toolbarWidget, {
36+
app.shell.addWidget(this.arduinoToolbarContainer, {
2337
area: 'top'
24-
})
38+
});
2539
}
2640
}

arduino-ide-extension/src/browser/toolbar/arduino-toolbar.tsx

+34-17
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export const ARDUINO_TOOLBAR_ITEM_CLASS = 'arduino-tool-item';
88

99
export namespace ArduinoToolbarComponent {
1010
export interface Props {
11+
side: 'left' | 'right',
1112
items: (TabBarToolbarItem | ReactTabBarToolbarItem)[],
1213
commands: CommandRegistry,
1314
commandIsEnabled: (id: string) => boolean,
@@ -29,25 +30,32 @@ export class ArduinoToolbarComponent extends React.Component<ArduinoToolbarCompo
2930
const command = this.props.commands.getCommand(item.command);
3031
const cls = `${ARDUINO_TOOLBAR_ITEM_CLASS} ${TabBarToolbar.Styles.TAB_BAR_TOOLBAR_ITEM} ${command && this.props.commandIsEnabled(command.id) ? ' enabled' : ''}`
3132
return <div key={item.id}
32-
className={cls} >
33-
<div
34-
key={item.id + '-icon'}
35-
id={item.id}
36-
className={`${item.id} arduino-tool-icon`}
37-
onClick={this.props.executeCommand}
38-
onMouseOver={() => this.setState({ tooltip: item.tooltip || '' })}
39-
onMouseOut={() => this.setState({ tooltip: '' })}
40-
title={item.tooltip}>
41-
{innerText}
42-
</div>
33+
className={cls} >
34+
<div
35+
key={item.id + '-icon'}
36+
id={item.id}
37+
className={`${item.id} arduino-tool-icon`}
38+
onClick={this.props.executeCommand}
39+
onMouseOver={() => this.setState({ tooltip: item.tooltip || '' })}
40+
onMouseOut={() => this.setState({ tooltip: '' })}
41+
title={item.tooltip}>
42+
{innerText}
4343
</div>
44+
</div>
4445
}
4546

4647
render(): React.ReactNode {
47-
return <React.Fragment>
48-
<div key='arduino-toolbar-tooltip' className={'arduino-toolbar-tooltip'}>{this.state.tooltip}</div>
49-
{[...this.props.items].map(item => TabBarToolbarItem.is(item) ? this.renderItem(item) : item.render())}
50-
</React.Fragment>;
48+
if (this.props.side === 'left') {
49+
return <React.Fragment>
50+
<div key='arduino-toolbar-tooltip' className={'arduino-toolbar-tooltip'}>{this.state.tooltip}</div>
51+
{[...this.props.items].map(item => TabBarToolbarItem.is(item) ? this.renderItem(item) : item.render())}
52+
</React.Fragment>;
53+
} else {
54+
return <React.Fragment>
55+
{[...this.props.items].map(item => TabBarToolbarItem.is(item) ? this.renderItem(item) : item.render())}
56+
<div key='arduino-toolbar-tooltip' className={'arduino-toolbar-tooltip'}>{this.state.tooltip}</div>
57+
</React.Fragment>;
58+
}
5159
}
5260
}
5361

@@ -58,10 +66,11 @@ export class ArduinoToolbar extends ReactWidget {
5866
constructor(
5967
protected readonly tabBarToolbarRegistry: TabBarToolbarRegistry,
6068
protected readonly commands: CommandRegistry,
61-
protected readonly labelParser: LabelParser
69+
protected readonly labelParser: LabelParser,
70+
public readonly side: 'left' | 'right'
6271
) {
6372
super();
64-
this.id = 'arduino-toolbar';
73+
this.id = side + '-arduino-toolbar';
6574
this.addClass(TabBarToolbar.Styles.TAB_BAR_TOOLBAR);
6675
this.init();
6776
this.tabBarToolbarRegistry.onDidChange(() => this.updateToolbar());
@@ -83,6 +92,7 @@ export class ArduinoToolbar extends ReactWidget {
8392

8493
protected init(): void {
8594
this.node.classList.add('theia-arduino-toolbar');
95+
this.node.classList.add(this.side);
8696
this.update();
8797
}
8898

@@ -93,6 +103,7 @@ export class ArduinoToolbar extends ReactWidget {
93103

94104
protected render(): React.ReactNode {
95105
return <ArduinoToolbarComponent
106+
side={this.side}
96107
items={[...this.items.values()]}
97108
commands={this.commands}
98109
commandIsEnabled={this.doCommandIsEnabled}
@@ -107,3 +118,9 @@ export class ArduinoToolbar extends ReactWidget {
107118
}
108119
}
109120
}
121+
122+
export namespace ArduinoToolbar {
123+
export function is(maybeToolbarWidget: any): maybeToolbarWidget is ArduinoToolbar {
124+
return maybeToolbarWidget instanceof ArduinoToolbar;
125+
}
126+
}

0 commit comments

Comments
 (0)