feat: Create remote sketch

Closes #1580

Signed-off-by: Akos Kitta <a.kitta@arduino.cc>
This commit is contained in:
Akos Kitta
2022-10-25 17:13:43 +02:00
committed by Akos Kitta
parent 6984c52b92
commit 7d6a2d5e33
21 changed files with 683 additions and 111 deletions

View File

@@ -0,0 +1,20 @@
import * as React from '@theia/core/shared/react';
export class CreateNew extends React.Component<CreateNew.Props> {
override render(): React.ReactNode {
return (
<div className="create-new">
<button className="theia-button secondary" onClick={this.props.onClick}>
{this.props.label}
</button>
</div>
);
}
}
export namespace CreateNew {
export interface Props {
readonly label: string;
readonly onClick: () => void;
}
}

View File

@@ -0,0 +1,93 @@
import * as React from '@theia/core/shared/react';
import * as ReactDOM from '@theia/core/shared/react-dom';
import { inject, injectable } from '@theia/core/shared/inversify';
import { nls } from '@theia/core/lib/common/nls';
import { Widget } from '@theia/core/shared/@phosphor/widgets';
import { Message, MessageLoop } from '@theia/core/shared/@phosphor/messaging';
import { Disposable } from '@theia/core/lib/common/disposable';
import { BaseWidget } from '@theia/core/lib/browser/widgets/widget';
import { CommandService } from '@theia/core/lib/common/command';
import { SketchbookTreeWidget } from './sketchbook-tree-widget';
import { CreateNew } from '../sketchbook/create-new';
@injectable()
export abstract class BaseSketchbookCompositeWidget<
TW extends SketchbookTreeWidget
> extends BaseWidget {
@inject(CommandService)
protected readonly commandService: CommandService;
private readonly compositeNode: HTMLElement;
private readonly footerNode: HTMLElement;
constructor() {
super();
this.compositeNode = document.createElement('div');
this.compositeNode.classList.add('composite-node');
this.footerNode = document.createElement('div');
this.footerNode.classList.add('footer-node');
this.compositeNode.appendChild(this.footerNode);
this.node.appendChild(this.compositeNode);
this.title.closable = false;
}
abstract get treeWidget(): TW;
protected abstract renderFooter(footerNode: HTMLElement): void;
protected updateFooter(): void {
this.renderFooter(this.footerNode);
}
protected override onAfterAttach(message: Message): void {
super.onAfterAttach(message);
Widget.attach(this.treeWidget, this.compositeNode);
this.renderFooter(this.footerNode);
this.toDisposeOnDetach.push(
Disposable.create(() => Widget.detach(this.treeWidget))
);
}
protected override onActivateRequest(message: Message): void {
super.onActivateRequest(message);
// Sending a resize message is needed because otherwise the tree widget would render empty
this.onResize(Widget.ResizeMessage.UnknownSize);
}
protected override onResize(message: Widget.ResizeMessage): void {
super.onResize(message);
MessageLoop.sendMessage(this.treeWidget, Widget.ResizeMessage.UnknownSize);
}
}
@injectable()
export class SketchbookCompositeWidget extends BaseSketchbookCompositeWidget<SketchbookTreeWidget> {
@inject(SketchbookTreeWidget)
private readonly sketchbookTreeWidget: SketchbookTreeWidget;
constructor() {
super();
this.id = 'sketchbook-composite-widget';
this.title.caption = nls.localize(
'arduino/sketch/titleLocalSketchbook',
'Local Sketchbook'
);
this.title.iconClass = 'sketchbook-tree-icon';
}
get treeWidget(): SketchbookTreeWidget {
return this.sketchbookTreeWidget;
}
protected renderFooter(footerNode: HTMLElement): void {
ReactDOM.render(
<CreateNew
label={nls.localize('arduino/sketchbook/newSketch', 'New Sketch')}
onClick={this.onDidClickCreateNew}
/>,
footerNode
);
}
private onDidClickCreateNew: () => void = () => {
this.commandService.executeCommand('arduino-new-sketch');
};
}

View File

@@ -59,6 +59,7 @@ export class SketchbookTreeWidget extends FileTreeWidget {
'Local Sketchbook'
);
this.title.closable = false;
this.addClass('tree-container'); // Adds `height: 100%` to the tree. Otherwise you cannot see it.
}
@postConstruct()

View File

@@ -11,15 +11,21 @@ import { Disposable } from '@theia/core/lib/common/disposable';
import { BaseWidget } from '@theia/core/lib/browser/widgets/widget';
import { SketchbookTreeWidget } from './sketchbook-tree-widget';
import { nls } from '@theia/core/lib/common';
import { CloudSketchbookCompositeWidget } from '../cloud-sketchbook/cloud-sketchbook-composite-widget';
import { URI } from '../../contributions/contribution';
import {
BaseSketchbookCompositeWidget,
SketchbookCompositeWidget,
} from './sketchbook-composite-widget';
@injectable()
export class SketchbookWidget extends BaseWidget {
static LABEL = nls.localize('arduino/sketch/titleSketchbook', 'Sketchbook');
static readonly LABEL = nls.localize(
'arduino/sketch/titleSketchbook',
'Sketchbook'
);
@inject(SketchbookTreeWidget)
protected readonly localSketchbookTreeWidget: SketchbookTreeWidget;
@inject(SketchbookCompositeWidget)
protected readonly sketchbookCompositeWidget: SketchbookCompositeWidget;
protected readonly sketchbookTreesContainer: DockPanel;
@@ -36,7 +42,7 @@ export class SketchbookWidget extends BaseWidget {
@postConstruct()
protected init(): void {
this.sketchbookTreesContainer.addWidget(this.localSketchbookTreeWidget);
this.sketchbookTreesContainer.addWidget(this.sketchbookCompositeWidget);
}
protected override onAfterAttach(message: Message): void {
@@ -48,7 +54,7 @@ export class SketchbookWidget extends BaseWidget {
}
getTreeWidget(): SketchbookTreeWidget {
return this.localSketchbookTreeWidget;
return this.sketchbookCompositeWidget.treeWidget;
}
activeTreeWidgetId(): string | undefined {
@@ -80,8 +86,8 @@ export class SketchbookWidget extends BaseWidget {
if (widget instanceof SketchbookTreeWidget) {
return widget;
}
if (widget instanceof CloudSketchbookCompositeWidget) {
return widget.getTreeWidget();
if (widget instanceof BaseSketchbookCompositeWidget) {
return widget.treeWidget;
}
return undefined;
};