Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/browser/panecomposite.ts
3294 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { Registry } from '../../platform/registry/common/platform.js';
7
import { Composite, CompositeDescriptor, CompositeRegistry } from './composite.js';
8
import { IConstructorSignature, BrandedService, IInstantiationService } from '../../platform/instantiation/common/instantiation.js';
9
import { URI } from '../../base/common/uri.js';
10
import { Dimension } from '../../base/browser/dom.js';
11
import { IActionViewItem } from '../../base/browser/ui/actionbar/actionbar.js';
12
import { IAction, Separator } from '../../base/common/actions.js';
13
import { MenuId, SubmenuItemAction } from '../../platform/actions/common/actions.js';
14
import { IContextMenuService } from '../../platform/contextview/browser/contextView.js';
15
import { IStorageService } from '../../platform/storage/common/storage.js';
16
import { ITelemetryService } from '../../platform/telemetry/common/telemetry.js';
17
import { IThemeService } from '../../platform/theme/common/themeService.js';
18
import { IWorkspaceContextService } from '../../platform/workspace/common/workspace.js';
19
import { ViewPaneContainer, ViewsSubMenu } from './parts/views/viewPaneContainer.js';
20
import { IPaneComposite } from '../common/panecomposite.js';
21
import { IView } from '../common/views.js';
22
import { IExtensionService } from '../services/extensions/common/extensions.js';
23
import { VIEWPANE_FILTER_ACTION } from './parts/views/viewPane.js';
24
import { IBoundarySashes } from '../../base/browser/ui/sash/sash.js';
25
import { IBaseActionViewItemOptions } from '../../base/browser/ui/actionbar/actionViewItems.js';
26
27
export abstract class PaneComposite extends Composite implements IPaneComposite {
28
29
private viewPaneContainer?: ViewPaneContainer;
30
31
constructor(
32
id: string,
33
@ITelemetryService telemetryService: ITelemetryService,
34
@IStorageService protected storageService: IStorageService,
35
@IInstantiationService protected instantiationService: IInstantiationService,
36
@IThemeService themeService: IThemeService,
37
@IContextMenuService protected contextMenuService: IContextMenuService,
38
@IExtensionService protected extensionService: IExtensionService,
39
@IWorkspaceContextService protected contextService: IWorkspaceContextService
40
) {
41
super(id, telemetryService, themeService, storageService);
42
}
43
44
override create(parent: HTMLElement): void {
45
super.create(parent);
46
this.viewPaneContainer = this._register(this.createViewPaneContainer(parent));
47
this._register(this.viewPaneContainer.onTitleAreaUpdate(() => this.updateTitleArea()));
48
this.viewPaneContainer.create(parent);
49
}
50
51
override setVisible(visible: boolean): void {
52
super.setVisible(visible);
53
this.viewPaneContainer?.setVisible(visible);
54
}
55
56
layout(dimension: Dimension): void {
57
this.viewPaneContainer?.layout(dimension);
58
}
59
60
setBoundarySashes(sashes: IBoundarySashes): void {
61
this.viewPaneContainer?.setBoundarySashes(sashes);
62
}
63
64
getOptimalWidth(): number {
65
return this.viewPaneContainer?.getOptimalWidth() ?? 0;
66
}
67
68
openView<T extends IView>(id: string, focus?: boolean): T | undefined {
69
return this.viewPaneContainer?.openView(id, focus) as T;
70
}
71
72
getViewPaneContainer(): ViewPaneContainer | undefined {
73
return this.viewPaneContainer;
74
}
75
76
override getActionsContext(): unknown {
77
return this.getViewPaneContainer()?.getActionsContext();
78
}
79
80
override getContextMenuActions(): readonly IAction[] {
81
return this.viewPaneContainer?.menuActions?.getContextMenuActions() ?? [];
82
}
83
84
override getMenuIds(): MenuId[] {
85
const result: MenuId[] = [];
86
if (this.viewPaneContainer?.menuActions) {
87
result.push(this.viewPaneContainer.menuActions.menuId);
88
if (this.viewPaneContainer.isViewMergedWithContainer()) {
89
result.push(this.viewPaneContainer.panes[0].menuActions.menuId);
90
}
91
}
92
return result;
93
}
94
95
override getActions(): readonly IAction[] {
96
const result = [];
97
if (this.viewPaneContainer?.menuActions) {
98
result.push(...this.viewPaneContainer.menuActions.getPrimaryActions());
99
if (this.viewPaneContainer.isViewMergedWithContainer()) {
100
const viewPane = this.viewPaneContainer.panes[0];
101
if (viewPane.shouldShowFilterInHeader()) {
102
result.push(VIEWPANE_FILTER_ACTION);
103
}
104
result.push(...viewPane.menuActions.getPrimaryActions());
105
}
106
}
107
return result;
108
}
109
110
override getSecondaryActions(): readonly IAction[] {
111
if (!this.viewPaneContainer?.menuActions) {
112
return [];
113
}
114
115
const viewPaneActions = this.viewPaneContainer.isViewMergedWithContainer() ? this.viewPaneContainer.panes[0].menuActions.getSecondaryActions() : [];
116
let menuActions = this.viewPaneContainer.menuActions.getSecondaryActions();
117
118
const viewsSubmenuActionIndex = menuActions.findIndex(action => action instanceof SubmenuItemAction && action.item.submenu === ViewsSubMenu);
119
if (viewsSubmenuActionIndex !== -1) {
120
const viewsSubmenuAction = <SubmenuItemAction>menuActions[viewsSubmenuActionIndex];
121
if (viewsSubmenuAction.actions.some(({ enabled }) => enabled)) {
122
if (menuActions.length === 1 && viewPaneActions.length === 0) {
123
menuActions = viewsSubmenuAction.actions.slice();
124
} else if (viewsSubmenuActionIndex !== 0) {
125
menuActions = [viewsSubmenuAction, ...menuActions.slice(0, viewsSubmenuActionIndex), ...menuActions.slice(viewsSubmenuActionIndex + 1)];
126
}
127
} else {
128
// Remove views submenu if none of the actions are enabled
129
menuActions.splice(viewsSubmenuActionIndex, 1);
130
}
131
}
132
133
if (menuActions.length && viewPaneActions.length) {
134
return [
135
...menuActions,
136
new Separator(),
137
...viewPaneActions
138
];
139
}
140
141
return menuActions.length ? menuActions : viewPaneActions;
142
}
143
144
override getActionViewItem(action: IAction, options: IBaseActionViewItemOptions): IActionViewItem | undefined {
145
return this.viewPaneContainer?.getActionViewItem(action, options);
146
}
147
148
override getTitle(): string {
149
return this.viewPaneContainer?.getTitle() ?? '';
150
}
151
152
override focus(): void {
153
super.focus();
154
this.viewPaneContainer?.focus();
155
}
156
157
protected abstract createViewPaneContainer(parent: HTMLElement): ViewPaneContainer;
158
}
159
160
161
/**
162
* A Pane Composite descriptor is a lightweight descriptor of a Pane Composite in the workbench.
163
*/
164
export class PaneCompositeDescriptor extends CompositeDescriptor<PaneComposite> {
165
166
static create<Services extends BrandedService[]>(
167
ctor: { new(...services: Services): PaneComposite },
168
id: string,
169
name: string,
170
cssClass?: string,
171
order?: number,
172
requestedIndex?: number,
173
iconUrl?: URI
174
): PaneCompositeDescriptor {
175
176
return new PaneCompositeDescriptor(ctor as IConstructorSignature<PaneComposite>, id, name, cssClass, order, requestedIndex, iconUrl);
177
}
178
179
private constructor(
180
ctor: IConstructorSignature<PaneComposite>,
181
id: string,
182
name: string,
183
cssClass?: string,
184
order?: number,
185
requestedIndex?: number,
186
readonly iconUrl?: URI
187
) {
188
super(ctor, id, name, cssClass, order, requestedIndex);
189
}
190
}
191
192
export const Extensions = {
193
Viewlets: 'workbench.contributions.viewlets',
194
Panels: 'workbench.contributions.panels',
195
Auxiliary: 'workbench.contributions.auxiliary',
196
};
197
198
export class PaneCompositeRegistry extends CompositeRegistry<PaneComposite> {
199
200
/**
201
* Registers a viewlet to the platform.
202
*/
203
registerPaneComposite(descriptor: PaneCompositeDescriptor): void {
204
super.registerComposite(descriptor);
205
}
206
207
/**
208
* Deregisters a viewlet to the platform.
209
*/
210
deregisterPaneComposite(id: string): void {
211
super.deregisterComposite(id);
212
}
213
214
/**
215
* Returns the viewlet descriptor for the given id or null if none.
216
*/
217
getPaneComposite(id: string): PaneCompositeDescriptor {
218
return this.getComposite(id) as PaneCompositeDescriptor;
219
}
220
221
/**
222
* Returns an array of registered viewlets known to the platform.
223
*/
224
getPaneComposites(): PaneCompositeDescriptor[] {
225
return this.getComposites() as PaneCompositeDescriptor[];
226
}
227
}
228
229
Registry.add(Extensions.Viewlets, new PaneCompositeRegistry());
230
Registry.add(Extensions.Panels, new PaneCompositeRegistry());
231
Registry.add(Extensions.Auxiliary, new PaneCompositeRegistry());
232
233