Skip to content

Sketchbook sidebar state #1102

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Jul 4, 2022
Original file line number Diff line number Diff line change
Expand Up @@ -832,6 +832,7 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {

bind(CloudSketchbookWidget).toSelf();
rebind(SketchbookWidget).toService(CloudSketchbookWidget);
bind(CommandContribution).toService(CloudSketchbookWidget);
bind(CloudSketchbookTreeWidget).toDynamicValue(({ container }) =>
createCloudSketchbookTreeWidget(container)
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ export class SketchControl extends SketchContribution {
});
}

protected isCloudSketch(uri: string): boolean {
isCloudSketch(uri: string): boolean {
try {
const cloudCacheLocation = this.localCacheFsProvider.from(new URI(uri));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,22 @@ import { FrontendApplication } from '@theia/core/lib/browser/frontend-applicatio
import { FocusTracker, Widget } from '@theia/core/lib/browser';
import { DEFAULT_WINDOW_HASH } from '@theia/core/lib/common/window';
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
import { WorkspaceService as TheiaWorkspaceService } from '@theia/workspace/lib/browser/workspace-service';
import {
WorkspaceInput,
WorkspaceService as TheiaWorkspaceService,
} from '@theia/workspace/lib/browser/workspace-service';
import { ConfigService } from '../../../common/protocol/config-service';
import {
SketchesService,
Sketch,
} from '../../../common/protocol/sketches-service';
import { BoardsServiceProvider } from '../../boards/boards-service-provider';
import { BoardsConfig } from '../../boards/boards-config';
import { Command } from '@theia/core';

interface WorkspaceOptions extends WorkspaceInput {
commands: Command[];
}

@injectable()
export class WorkspaceService extends TheiaWorkspaceService {
Expand All @@ -42,6 +50,7 @@ export class WorkspaceService extends TheiaWorkspaceService {
protected readonly boardsServiceProvider: BoardsServiceProvider;

private version?: string;
private optionsToAppendToURI?: WorkspaceOptions;

async onStart(application: FrontendApplication): Promise<void> {
const info = await this.applicationServer.getApplicationInfo();
Expand Down Expand Up @@ -82,13 +91,25 @@ export class WorkspaceService extends TheiaWorkspaceService {
}
}

override open(uri: URI, options?: WorkspaceOptions): void {
this.optionsToAppendToURI = options;
super.doOpen(uri);
}

protected override openNewWindow(workspacePath: string): void {
const { boardsConfig } = this.boardsServiceProvider;
const url = BoardsConfig.Config.setConfig(
boardsConfig,
new URL(window.location.href)
); // Set the current boards config for the new browser window.
url.hash = workspacePath;
if (this.optionsToAppendToURI) {
url.searchParams.set(
'commands',
encodeURIComponent(JSON.stringify(this.optionsToAppendToURI?.commands))
);
this.optionsToAppendToURI = undefined;
}
this.windowService.openNewWindow(url.toString());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ import {
} from '@theia/core/lib/browser/preferences/preference-service';
import { ArduinoMenus, PlaceholderMenuNode } from '../../menu/arduino-menus';
import { SketchbookCommands } from '../sketchbook/sketchbook-commands';
import { CurrentSketch, SketchesServiceClientImpl } from '../../../common/protocol/sketches-service-client-impl';
import {
CurrentSketch,
SketchesServiceClientImpl,
} from '../../../common/protocol/sketches-service-client-impl';
import { Contribution } from '../../contributions/contribution';
import { ArduinoPreferences } from '../../arduino-preferences';
import { MainMenuManager } from '../../../common/main-menu-manager';
Expand Down Expand Up @@ -61,6 +64,14 @@ export namespace CloudSketchbookCommands {
}
}

export const SHOW_CLOUD_SKETCHBOOK_WIDGET = Command.toLocalizedCommand(
{
id: 'arduino-cloud-sketchbook--show-cloud-sketchbook-widget',
label: 'Show Cloud Sketchbook Widget',
},
'arduino/sketch/showCloudSketchbookWidget'
);

export const TOGGLE_CLOUD_SKETCHBOOK = Command.toLocalizedCommand(
{
id: 'arduino-cloud-sketchbook--disable',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,33 @@
import { inject, injectable, postConstruct } from '@theia/core/shared/inversify';
import {
inject,
injectable,
postConstruct,
} from '@theia/core/shared/inversify';
import { CloudSketchbookCompositeWidget } from './cloud-sketchbook-composite-widget';
import { SketchbookWidget } from '../sketchbook/sketchbook-widget';
import { ArduinoPreferences } from '../../arduino-preferences';
import { CommandContribution, CommandRegistry } from '@theia/core';
import { ApplicationShell } from '@theia/core/lib/browser';
import { CloudSketchbookCommands } from './cloud-sketchbook-contributions';
import { EditorManager } from '@theia/editor/lib/browser';

@injectable()
export class CloudSketchbookWidget extends SketchbookWidget {
export class CloudSketchbookWidget
extends SketchbookWidget
implements CommandContribution
{
@inject(CloudSketchbookCompositeWidget)
protected readonly widget: CloudSketchbookCompositeWidget;
protected readonly cloudSketchbookCompositeWidget: CloudSketchbookCompositeWidget;

@inject(ArduinoPreferences)
protected readonly arduinoPreferences: ArduinoPreferences;

@inject(ApplicationShell)
protected readonly shell: ApplicationShell;

@inject(EditorManager)
protected readonly editorManager: EditorManager;

@postConstruct()
protected override init(): void {
super.init();
Expand All @@ -27,7 +44,9 @@ export class CloudSketchbookWidget extends SketchbookWidget {

checkCloudEnabled() {
if (this.arduinoPreferences['arduino.cloud.enabled']) {
this.sketchbookTreesContainer.activateWidget(this.widget);
this.sketchbookTreesContainer.activateWidget(
this.cloudSketchbookCompositeWidget
);
} else {
this.sketchbookTreesContainer.activateWidget(
this.localSketchbookTreeWidget
Expand All @@ -45,7 +64,9 @@ export class CloudSketchbookWidget extends SketchbookWidget {
}

protected override onAfterAttach(msg: any): void {
this.sketchbookTreesContainer.addWidget(this.widget);
this.sketchbookTreesContainer.addWidget(
this.cloudSketchbookCompositeWidget
);
this.setDocumentMode();
this.arduinoPreferences.onPreferenceChanged((event) => {
if (event.preferenceName === 'arduino.cloud.enabled') {
Expand All @@ -54,4 +75,28 @@ export class CloudSketchbookWidget extends SketchbookWidget {
});
super.onAfterAttach(msg);
}

registerCommands(registry: CommandRegistry): void {
this.sketchbookTreesContainer.addWidget(
this.cloudSketchbookCompositeWidget
);
registry.registerCommand(
CloudSketchbookCommands.SHOW_CLOUD_SKETCHBOOK_WIDGET,
{
execute: () => this.showCloudSketchbookWidget(),
}
);
}

showCloudSketchbookWidget(): void {
if (this.arduinoPreferences['arduino.cloud.enabled']) {
this.shell.activateWidget(this.id).then((widget) => {
if (widget instanceof CloudSketchbookWidget) {
widget.activateTreeWidget(this.cloudSketchbookCompositeWidget.id);
}
if (this.editorManager.currentEditor)
this.shell.activateWidget(this.editorManager.currentEditor.id);
});
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
import { Command } from '@theia/core/lib/common/command';

export namespace SketchbookCommands {
export const TOGGLE_SKETCHBOOK_WIDGET: Command = {
id: 'arduino-sketchbook-widget:toggle',
};

export const SHOW_SKETCHBOOK_WIDGET = Command.toLocalizedCommand(
{
id: 'arduino-sketchbook--show-sketchbook-widget',
label: 'Show Sketchbook Widget',
},
'arduino/sketch/showSketchbookWidget'
);

export const OPEN_NEW_WINDOW = Command.toLocalizedCommand(
{
id: 'arduino-sketchbook--open-sketch-new-window',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as remote from '@theia/core/electron-shared/@electron/remote';
import { inject, injectable } from '@theia/core/shared/inversify';
import { CommandRegistry } from '@theia/core/lib/common/command';
import { Command, CommandRegistry } from '@theia/core/lib/common/command';
import { MenuModelRegistry } from '@theia/core/lib/common/menu';
import { PreferenceService } from '@theia/core/lib/browser/preferences/preference-service';
import { AbstractViewContribution } from '@theia/core/lib/browser/shell/view-contribution';
Expand Down Expand Up @@ -29,6 +29,10 @@ import {
} from '../../../common/protocol/sketches-service-client-impl';
import { FileService } from '@theia/filesystem/lib/browser/file-service';
import { URI } from '../../contributions/contribution';
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
import { EditorManager } from '@theia/editor/lib/browser';
import { SketchControl } from '../../contributions/sketch-control';
import { CloudSketchbookCommands } from '../cloud-sketchbook/cloud-sketchbook-contributions';

export const SKETCHBOOK__CONTEXT = ['arduino-sketchbook--context'];

Expand Down Expand Up @@ -67,6 +71,18 @@ export class SketchbookWidgetContribution
@inject(FileService)
protected readonly fileService: FileService;

@inject(CommandRegistry)
protected readonly commandRegistry: CommandRegistry;

@inject(FrontendApplicationStateService)
private readonly app: FrontendApplicationStateService;

@inject(EditorManager)
protected readonly editorManager: EditorManager;

@inject(SketchControl)
protected readonly sketchControl: SketchControl;

protected readonly toDisposeBeforeNewContextMenu = new DisposableCollection();

constructor() {
Expand All @@ -77,7 +93,7 @@ export class SketchbookWidgetContribution
area: 'left',
rank: 1,
},
toggleCommandId: 'arduino-sketchbook-widget:toggle',
toggleCommandId: SketchbookCommands.TOGGLE_SKETCHBOOK_WIDGET.id,
toggleKeybinding: 'CtrlCmd+Shift+B',
});
}
Expand All @@ -92,6 +108,12 @@ export class SketchbookWidgetContribution
this.mainMenuManager.update();
}
});

this.app.reachedState('ready').then(() => this.onReady());
}

onReady(): void {
this.runEncodedCommands();
}

async initializeLayout(): Promise<void> {
Expand All @@ -100,11 +122,11 @@ export class SketchbookWidgetContribution

override registerCommands(registry: CommandRegistry): void {
super.registerCommands(registry);

registry.registerCommand(SketchbookCommands.SHOW_SKETCHBOOK_WIDGET, {
execute: () => this.showSketchbookWidget(),
});
registry.registerCommand(SketchbookCommands.OPEN_NEW_WINDOW, {
execute: async (arg) => {
return this.workspaceService.open(arg.node.uri);
},
execute: (arg) => this.openSketchInNewWindow(arg),
isEnabled: (arg) =>
!!arg && 'node' in arg && SketchbookTree.SketchDirNode.is(arg.node),
isVisible: (arg) =>
Expand Down Expand Up @@ -192,12 +214,21 @@ export class SketchbookWidgetContribution
});
}

openSketchInNewWindow(arg: any): any {
const openSketchbookCommand = this.sketchControl.isCloudSketch(arg.node.uri)
? CloudSketchbookCommands.SHOW_CLOUD_SKETCHBOOK_WIDGET
: SketchbookCommands.SHOW_SKETCHBOOK_WIDGET;
return this.workspaceService.open(arg.node.uri, {
commands: [openSketchbookCommand],
});
}

override registerMenus(registry: MenuModelRegistry): void {
super.registerMenus(registry);

// unregister main menu action
registry.unregisterMenuAction({
commandId: 'arduino-sketchbook-widget:toggle',
commandId: SketchbookCommands.TOGGLE_SKETCHBOOK_WIDGET.id,
});

registry.registerMenuAction(SKETCHBOOK__CONTEXT__MAIN_GROUP, {
Expand Down Expand Up @@ -230,4 +261,31 @@ export class SketchbookWidgetContribution
protected onCurrentWidgetChangedHandler(): void {
this.selectWidgetFileNode(this.shell.currentWidget);
}

protected async showSketchbookWidget(): Promise<void> {
this.widget
.then((widget) => this.shell.activateWidget(widget.id))
.then((widget) => {
if (widget instanceof SketchbookWidget) {
widget.activateTreeWidget(widget.getTreeWidget().id);
if (this.editorManager.currentEditor)
this.shell.activateWidget(this.editorManager.currentEditor.id);
}
});
}

protected runEncodedCommands(): void {
const params = new URLSearchParams(window.location.search);
const encoded = params.get('commands');
if (!encoded) return;

const commands = JSON.parse(decodeURIComponent(encoded));

if (commands && Array.isArray(commands)) {
commands.forEach((c: Command) => {
if (this.commandRegistry.commandIds.includes(c.id))
this.commandRegistry.executeCommand(c.id);
});
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { inject, injectable, postConstruct } from '@theia/core/shared/inversify';
import {
inject,
injectable,
postConstruct,
} from '@theia/core/shared/inversify';
import { toArray } from '@theia/core/shared/@phosphor/algorithm';
import { IDragEvent } from '@theia/core/shared/@phosphor/dragdrop';
import { DockPanel, Widget } from '@theia/core/shared/@phosphor/widgets';
Expand Down Expand Up @@ -45,6 +49,16 @@ export class SketchbookWidget extends BaseWidget {
return this.localSketchbookTreeWidget;
}

activateTreeWidget(treeWidgetId: string): boolean {
for (const widget of toArray(this.sketchbookTreesContainer.widgets())) {
if (widget.id === treeWidgetId) {
this.sketchbookTreesContainer.activateWidget(widget);
return true;
}
}
return false;
}

protected override onActivateRequest(message: Message): void {
super.onActivateRequest(message);

Expand Down