Path: blob/main/src/vs/workbench/browser/panecomposite.ts
3294 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { Registry } from '../../platform/registry/common/platform.js';6import { Composite, CompositeDescriptor, CompositeRegistry } from './composite.js';7import { IConstructorSignature, BrandedService, IInstantiationService } from '../../platform/instantiation/common/instantiation.js';8import { URI } from '../../base/common/uri.js';9import { Dimension } from '../../base/browser/dom.js';10import { IActionViewItem } from '../../base/browser/ui/actionbar/actionbar.js';11import { IAction, Separator } from '../../base/common/actions.js';12import { MenuId, SubmenuItemAction } from '../../platform/actions/common/actions.js';13import { IContextMenuService } from '../../platform/contextview/browser/contextView.js';14import { IStorageService } from '../../platform/storage/common/storage.js';15import { ITelemetryService } from '../../platform/telemetry/common/telemetry.js';16import { IThemeService } from '../../platform/theme/common/themeService.js';17import { IWorkspaceContextService } from '../../platform/workspace/common/workspace.js';18import { ViewPaneContainer, ViewsSubMenu } from './parts/views/viewPaneContainer.js';19import { IPaneComposite } from '../common/panecomposite.js';20import { IView } from '../common/views.js';21import { IExtensionService } from '../services/extensions/common/extensions.js';22import { VIEWPANE_FILTER_ACTION } from './parts/views/viewPane.js';23import { IBoundarySashes } from '../../base/browser/ui/sash/sash.js';24import { IBaseActionViewItemOptions } from '../../base/browser/ui/actionbar/actionViewItems.js';2526export abstract class PaneComposite extends Composite implements IPaneComposite {2728private viewPaneContainer?: ViewPaneContainer;2930constructor(31id: string,32@ITelemetryService telemetryService: ITelemetryService,33@IStorageService protected storageService: IStorageService,34@IInstantiationService protected instantiationService: IInstantiationService,35@IThemeService themeService: IThemeService,36@IContextMenuService protected contextMenuService: IContextMenuService,37@IExtensionService protected extensionService: IExtensionService,38@IWorkspaceContextService protected contextService: IWorkspaceContextService39) {40super(id, telemetryService, themeService, storageService);41}4243override create(parent: HTMLElement): void {44super.create(parent);45this.viewPaneContainer = this._register(this.createViewPaneContainer(parent));46this._register(this.viewPaneContainer.onTitleAreaUpdate(() => this.updateTitleArea()));47this.viewPaneContainer.create(parent);48}4950override setVisible(visible: boolean): void {51super.setVisible(visible);52this.viewPaneContainer?.setVisible(visible);53}5455layout(dimension: Dimension): void {56this.viewPaneContainer?.layout(dimension);57}5859setBoundarySashes(sashes: IBoundarySashes): void {60this.viewPaneContainer?.setBoundarySashes(sashes);61}6263getOptimalWidth(): number {64return this.viewPaneContainer?.getOptimalWidth() ?? 0;65}6667openView<T extends IView>(id: string, focus?: boolean): T | undefined {68return this.viewPaneContainer?.openView(id, focus) as T;69}7071getViewPaneContainer(): ViewPaneContainer | undefined {72return this.viewPaneContainer;73}7475override getActionsContext(): unknown {76return this.getViewPaneContainer()?.getActionsContext();77}7879override getContextMenuActions(): readonly IAction[] {80return this.viewPaneContainer?.menuActions?.getContextMenuActions() ?? [];81}8283override getMenuIds(): MenuId[] {84const result: MenuId[] = [];85if (this.viewPaneContainer?.menuActions) {86result.push(this.viewPaneContainer.menuActions.menuId);87if (this.viewPaneContainer.isViewMergedWithContainer()) {88result.push(this.viewPaneContainer.panes[0].menuActions.menuId);89}90}91return result;92}9394override getActions(): readonly IAction[] {95const result = [];96if (this.viewPaneContainer?.menuActions) {97result.push(...this.viewPaneContainer.menuActions.getPrimaryActions());98if (this.viewPaneContainer.isViewMergedWithContainer()) {99const viewPane = this.viewPaneContainer.panes[0];100if (viewPane.shouldShowFilterInHeader()) {101result.push(VIEWPANE_FILTER_ACTION);102}103result.push(...viewPane.menuActions.getPrimaryActions());104}105}106return result;107}108109override getSecondaryActions(): readonly IAction[] {110if (!this.viewPaneContainer?.menuActions) {111return [];112}113114const viewPaneActions = this.viewPaneContainer.isViewMergedWithContainer() ? this.viewPaneContainer.panes[0].menuActions.getSecondaryActions() : [];115let menuActions = this.viewPaneContainer.menuActions.getSecondaryActions();116117const viewsSubmenuActionIndex = menuActions.findIndex(action => action instanceof SubmenuItemAction && action.item.submenu === ViewsSubMenu);118if (viewsSubmenuActionIndex !== -1) {119const viewsSubmenuAction = <SubmenuItemAction>menuActions[viewsSubmenuActionIndex];120if (viewsSubmenuAction.actions.some(({ enabled }) => enabled)) {121if (menuActions.length === 1 && viewPaneActions.length === 0) {122menuActions = viewsSubmenuAction.actions.slice();123} else if (viewsSubmenuActionIndex !== 0) {124menuActions = [viewsSubmenuAction, ...menuActions.slice(0, viewsSubmenuActionIndex), ...menuActions.slice(viewsSubmenuActionIndex + 1)];125}126} else {127// Remove views submenu if none of the actions are enabled128menuActions.splice(viewsSubmenuActionIndex, 1);129}130}131132if (menuActions.length && viewPaneActions.length) {133return [134...menuActions,135new Separator(),136...viewPaneActions137];138}139140return menuActions.length ? menuActions : viewPaneActions;141}142143override getActionViewItem(action: IAction, options: IBaseActionViewItemOptions): IActionViewItem | undefined {144return this.viewPaneContainer?.getActionViewItem(action, options);145}146147override getTitle(): string {148return this.viewPaneContainer?.getTitle() ?? '';149}150151override focus(): void {152super.focus();153this.viewPaneContainer?.focus();154}155156protected abstract createViewPaneContainer(parent: HTMLElement): ViewPaneContainer;157}158159160/**161* A Pane Composite descriptor is a lightweight descriptor of a Pane Composite in the workbench.162*/163export class PaneCompositeDescriptor extends CompositeDescriptor<PaneComposite> {164165static create<Services extends BrandedService[]>(166ctor: { new(...services: Services): PaneComposite },167id: string,168name: string,169cssClass?: string,170order?: number,171requestedIndex?: number,172iconUrl?: URI173): PaneCompositeDescriptor {174175return new PaneCompositeDescriptor(ctor as IConstructorSignature<PaneComposite>, id, name, cssClass, order, requestedIndex, iconUrl);176}177178private constructor(179ctor: IConstructorSignature<PaneComposite>,180id: string,181name: string,182cssClass?: string,183order?: number,184requestedIndex?: number,185readonly iconUrl?: URI186) {187super(ctor, id, name, cssClass, order, requestedIndex);188}189}190191export const Extensions = {192Viewlets: 'workbench.contributions.viewlets',193Panels: 'workbench.contributions.panels',194Auxiliary: 'workbench.contributions.auxiliary',195};196197export class PaneCompositeRegistry extends CompositeRegistry<PaneComposite> {198199/**200* Registers a viewlet to the platform.201*/202registerPaneComposite(descriptor: PaneCompositeDescriptor): void {203super.registerComposite(descriptor);204}205206/**207* Deregisters a viewlet to the platform.208*/209deregisterPaneComposite(id: string): void {210super.deregisterComposite(id);211}212213/**214* Returns the viewlet descriptor for the given id or null if none.215*/216getPaneComposite(id: string): PaneCompositeDescriptor {217return this.getComposite(id) as PaneCompositeDescriptor;218}219220/**221* Returns an array of registered viewlets known to the platform.222*/223getPaneComposites(): PaneCompositeDescriptor[] {224return this.getComposites() as PaneCompositeDescriptor[];225}226}227228Registry.add(Extensions.Viewlets, new PaneCompositeRegistry());229Registry.add(Extensions.Panels, new PaneCompositeRegistry());230Registry.add(Extensions.Auxiliary, new PaneCompositeRegistry());231232233