// ***************************************************************************** // Copyright (C) 2019 TypeFox and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at // http://www.eclipse.org/legal/epl-2.0. // // This Source Code may also be made available under the following Secondary // Licenses when the conditions for such availability set forth in the Eclipse // Public License v. 2.0 are satisfied: GNU General Public License, version 2 // with the GNU Classpath Exception which is available at // https://www.gnu.org/software/classpath/license.html. // // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 // ***************************************************************************** import { injectable, inject, postConstruct } from '@theia/core/shared/inversify'; import { Panel, Widget } from '@theia/core/shared/@lumino/widgets'; import { MenuModelRegistry } from '@theia/core/lib/common/menu'; import { CommandRegistry } from '@theia/core/lib/common/command'; import { StatefulWidget } from '@theia/core/lib/browser/shell/shell-layout-restorer'; import { Message } from '@theia/core/shared/@lumino/messaging'; import { TreeViewWidget } from './tree-view-widget'; import { DescriptionWidget, DynamicToolbarWidget } from '@theia/core/lib/browser/view-container'; import { DisposableCollection, Emitter, Event } from '@theia/core/lib/common'; import { ContextKeyService } from '@theia/core/lib/browser/context-key-service'; @injectable() export class PluginViewWidgetIdentifier { id: string; viewId: string; } @injectable() export class PluginViewWidget extends Panel implements StatefulWidget, DescriptionWidget, DynamicToolbarWidget { currentViewContainerId?: string; protected _message?: string; protected _description: string = ''; protected _suppressUpdateViewVisibility = false; protected updatingViewVisibility = false; protected onDidChangeDescriptionEmitter = new Emitter(); protected toDispose = new DisposableCollection(this.onDidChangeDescriptionEmitter); protected readonly onDidChangeToolbarItemsEmitter = new Emitter(); get onDidChangeToolbarItems(): Event { return this.onDidChangeToolbarItemsEmitter.event; } @inject(MenuModelRegistry) protected readonly menus: MenuModelRegistry; @inject(CommandRegistry) protected readonly commands: CommandRegistry; @inject(ContextKeyService) protected readonly contextKeyService: ContextKeyService; @inject(PluginViewWidgetIdentifier) readonly options: PluginViewWidgetIdentifier; constructor() { super(); this.node.tabIndex = -1; this.node.style.height = '100%'; } @postConstruct() protected init(): void { this.id = this.options.id; const localContext = this.contextKeyService.createScoped(this.node); localContext.setContext('view', this.options.viewId); } get onDidChangeDescription(): Event { return this.onDidChangeDescriptionEmitter.event; } protected override onActivateRequest(msg: Message): void { super.onActivateRequest(msg); const widget = this.widgets[0]; if (widget) { widget.activate(); this.updateWidgetMessage(); } else { this.node.focus(); } } storeState(): PluginViewWidget.State { return { label: this.title.label, message: this.message, widgets: this.widgets, suppressUpdateViewVisibility: this._suppressUpdateViewVisibility, currentViewContainerId: this.currentViewContainerId }; } restoreState(state: PluginViewWidget.State): void { this.title.label = state.label; this.message = state.message; this.suppressUpdateViewVisibility = state.suppressUpdateViewVisibility; this.currentViewContainerId = state.currentViewContainerId; for (const widget of state.widgets) { this.addWidget(widget); } } set suppressUpdateViewVisibility(suppressUpdateViewVisibility: boolean) { this._suppressUpdateViewVisibility = !this.updatingViewVisibility && suppressUpdateViewVisibility; } updateViewVisibility(cb: () => void): void { if (this._suppressUpdateViewVisibility) { return; } try { this.updatingViewVisibility = true; cb(); } finally { this.updatingViewVisibility = false; } } get message(): string | undefined { return this._message; } set message(message: string | undefined) { this._message = message; this.updateWidgetMessage(); } get description(): string { return this._description; } set description(description: string) { this._description = description; this.onDidChangeDescriptionEmitter.fire(); } private updateWidgetMessage(): void { const widget = this.widgets[0]; if (widget) { if (widget instanceof TreeViewWidget) { widget.message = this._message; } } } override addWidget(widget: Widget): void { super.addWidget(widget); this.updateWidgetMessage(); this.onDidChangeToolbarItemsEmitter.fire(); } override insertWidget(index: number, widget: Widget): void { super.insertWidget(index, widget); this.updateWidgetMessage(); this.onDidChangeToolbarItemsEmitter.fire(); } override dispose(): void { this.toDispose.dispose(); super.dispose(); } } export namespace PluginViewWidget { export interface State { label: string, message?: string, widgets: ReadonlyArray, suppressUpdateViewVisibility: boolean; currentViewContainerId: string | undefined; } }