Skip to content

Commit 044a280

Browse files
committed
1 parent e340b53 commit 044a280

6 files changed

Lines changed: 106 additions & 5 deletions

File tree

src/vs/platform/actions/common/actions.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ export class MenuId {
111111
static readonly TunnelInline = new MenuId('TunnelInline');
112112
static readonly TunnelTitle = new MenuId('TunnelTitle');
113113
static readonly ViewItemContext = new MenuId('ViewItemContext');
114+
static readonly ViewContainerTitleContext = new MenuId('ViewContainerTitleContext');
114115
static readonly ViewTitle = new MenuId('ViewTitle');
115116
static readonly ViewTitleContext = new MenuId('ViewTitleContext');
116117
static readonly CommentThreadTitle = new MenuId('CommentThreadTitle');

src/vs/workbench/browser/panecomposite.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,14 @@ import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace
1616
import { ViewPaneContainer } from './parts/views/viewPaneContainer';
1717
import { IPaneComposite } from 'vs/workbench/common/panecomposite';
1818
import { IAction, IActionViewItem } from 'vs/base/common/actions';
19+
import { ViewContainerMenuActions } from 'vs/workbench/browser/parts/views/viewMenuActions';
20+
import { MenuId } from 'vs/platform/actions/common/actions';
21+
import { Separator } from 'vs/base/browser/ui/actionbar/actionbar';
1922

2023
export class PaneComposite extends Composite implements IPaneComposite {
2124

25+
private menuActions: ViewContainerMenuActions;
26+
2227
constructor(
2328
id: string,
2429
protected readonly viewPaneContainer: ViewPaneContainer,
@@ -39,6 +44,7 @@ export class PaneComposite extends Composite implements IPaneComposite {
3944
) {
4045
super(id, telemetryService, themeService, storageService);
4146

47+
this.menuActions = this._register(this.instantiationService.createInstance(ViewContainerMenuActions, this.getId(), MenuId.ViewContainerTitleContext));
4248
this._register(this.viewPaneContainer.onTitleAreaUpdate(() => this.updateTitleArea()));
4349
}
4450

@@ -68,7 +74,15 @@ export class PaneComposite extends Composite implements IPaneComposite {
6874
}
6975

7076
getContextMenuActions(): ReadonlyArray<IAction> {
71-
return this.viewPaneContainer.getContextMenuActions();
77+
const result = [];
78+
result.push(...this.menuActions.getContextMenuActions());
79+
80+
if (result.length) {
81+
result.push(new Separator());
82+
}
83+
84+
result.push(...this.viewPaneContainer.getContextMenuActions());
85+
return result;
7286
}
7387

7488
getActions(): ReadonlyArray<IAction> {

src/vs/workbench/browser/parts/panel/panelPart.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
3535
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
3636
import { ViewContainer, IViewDescriptorService, IViewContainerModel, ViewContainerLocation } from 'vs/workbench/common/views';
3737
import { MenuId } from 'vs/platform/actions/common/actions';
38-
import { ViewMenuActions } from 'vs/workbench/browser/parts/views/viewMenuActions';
38+
import { ViewMenuActions, ViewContainerMenuActions } from 'vs/workbench/browser/parts/views/viewMenuActions';
3939
import { IPaneComposite } from 'vs/workbench/common/panecomposite';
4040
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
4141
import { Before2D, CompositeDragAndDropObserver, ICompositeDragAndDrop } from 'vs/workbench/browser/dnd';
@@ -196,6 +196,10 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
196196
result.push(...viewMenuActions.getContextMenuActions());
197197
viewMenuActions.dispose();
198198
}
199+
200+
const viewContainerMenuActions = this.instantiationService.createInstance(ViewContainerMenuActions, container.id, MenuId.ViewContainerTitleContext);
201+
result.push(...viewContainerMenuActions.getContextMenuActions());
202+
viewContainerMenuActions.dispose();
199203
}
200204
return result;
201205
}

src/vs/workbench/browser/parts/views/viewMenuActions.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,37 @@ export class ViewMenuActions extends Disposable {
6969
return this.contextMenuActions;
7070
}
7171
}
72+
73+
export class ViewContainerMenuActions extends Disposable {
74+
75+
private readonly titleActionsDisposable = this._register(new MutableDisposable());
76+
private contextMenuActions: IAction[] = [];
77+
78+
constructor(
79+
containerId: string,
80+
contextMenuId: MenuId,
81+
@IContextKeyService private readonly contextKeyService: IContextKeyService,
82+
@IMenuService private readonly menuService: IMenuService,
83+
) {
84+
super();
85+
86+
const scopedContextKeyService = this._register(this.contextKeyService.createScoped());
87+
scopedContextKeyService.createKey('container', containerId);
88+
89+
const contextMenu = this._register(this.menuService.createMenu(contextMenuId, scopedContextKeyService));
90+
const updateContextMenuActions = () => {
91+
this.contextMenuActions = [];
92+
this.titleActionsDisposable.value = createAndFillInActionBarActions(contextMenu, { shouldForwardArgs: true }, { primary: [], secondary: this.contextMenuActions });
93+
};
94+
this._register(contextMenu.onDidChange(updateContextMenuActions));
95+
updateContextMenuActions();
96+
97+
this._register(toDisposable(() => {
98+
this.contextMenuActions = [];
99+
}));
100+
}
101+
102+
getContextMenuActions(): IAction[] {
103+
return this.contextMenuActions;
104+
}
105+
}

src/vs/workbench/browser/parts/views/viewsService.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,8 +186,8 @@ export class ViewsService extends Disposable implements IViewsService {
186186
super({
187187
id: `${viewDescriptor.id}.resetViewLocation`,
188188
title: {
189-
original: 'Reset View Location',
190-
value: localize('resetViewLocation', "Reset View Location")
189+
original: 'Reset Location',
190+
value: localize('resetViewLocation', "Reset Location")
191191
},
192192
menu: [{
193193
id: MenuId.ViewTitleContext,

src/vs/workbench/services/views/browser/viewDescriptorService.ts

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import { ViewContainerLocation, IViewDescriptorService, ViewContainer, IViewsRegistry, IViewContainersRegistry, IViewDescriptor, Extensions as ViewExtensions } from 'vs/workbench/common/views';
7-
import { IContextKey, RawContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
7+
import { IContextKey, RawContextKey, IContextKeyService, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
88
import { IStorageService, StorageScope, IWorkspaceStorageChangeEvent } from 'vs/platform/storage/common/storage';
99
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
1010
import { Registry } from 'vs/platform/registry/common/platform';
@@ -18,6 +18,8 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
1818
import { generateUuid } from 'vs/base/common/uuid';
1919
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
2020
import { ViewContainerModel } from 'vs/workbench/services/views/common/viewContainerModel';
21+
import { registerAction2, Action2, MenuId } from 'vs/platform/actions/common/actions';
22+
import { localize } from 'vs/nls';
2123

2224
interface ICachedViewContainerInfo {
2325
containerId: string;
@@ -44,6 +46,7 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor
4446
private readonly activeViewContextKeys: Map<string, IContextKey<boolean>>;
4547
private readonly movableViewContextKeys: Map<string, IContextKey<boolean>>;
4648
private readonly defaultViewLocationContextKeys: Map<string, IContextKey<boolean>>;
49+
private readonly defaultViewContainerLocationContextKeys: Map<string, IContextKey<boolean>>;
4750

4851
private readonly viewsRegistry: IViewsRegistry;
4952
private readonly viewContainersRegistry: IViewContainersRegistry;
@@ -103,6 +106,7 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor
103106
this.activeViewContextKeys = new Map<string, IContextKey<boolean>>();
104107
this.movableViewContextKeys = new Map<string, IContextKey<boolean>>();
105108
this.defaultViewLocationContextKeys = new Map<string, IContextKey<boolean>>();
109+
this.defaultViewContainerLocationContextKeys = new Map<string, IContextKey<boolean>>();
106110

107111
this.viewContainersRegistry = Registry.as<IViewContainersRegistry>(ViewExtensions.ViewContainersRegistry);
108112
this.viewsRegistry = Registry.as<IViewsRegistry>(ViewExtensions.ViewsRegistry);
@@ -297,6 +301,9 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor
297301
if (from !== to) {
298302
this.cachedViewContainerInfo.set(viewContainer.id, to);
299303

304+
const defaultLocation = this.isGeneratedContainerId(viewContainer.id) ? true : this.getViewContainerLocation(viewContainer) === this.getDefaultViewContainerLocation(viewContainer);
305+
this.getOrCreateDefaultViewContainerLocationContextKey(viewContainer).set(defaultLocation);
306+
300307
this._onDidChangeContainerLocation.fire({ viewContainer, from, to });
301308

302309
const views = this.getViewsByContainer(viewContainer);
@@ -590,6 +597,8 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor
590597
}
591598

592599
private onDidRegisterViewContainer(viewContainer: ViewContainer): void {
600+
const defaultLocation = this.isGeneratedContainerId(viewContainer.id) ? true : this.getViewContainerLocation(viewContainer) === this.getDefaultViewContainerLocation(viewContainer);
601+
this.getOrCreateDefaultViewContainerLocationContextKey(viewContainer).set(defaultLocation);
593602
this.getOrRegisterViewContainerModel(viewContainer);
594603
}
595604

@@ -603,6 +612,8 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor
603612
this.onDidChangeActiveViews({ added: viewContainerModel.activeViewDescriptors, removed: [] });
604613
viewContainerModel.onDidChangeActiveViewDescriptors(changed => this.onDidChangeActiveViews(changed), this, disposables);
605614

615+
disposables.add(this.registerResetViewContainerAction(viewContainer));
616+
606617
this.viewContainerModels.set(viewContainer, { viewContainerModel: viewContainerModel, disposable: disposables });
607618

608619
// Register all views that were statically registered to this container
@@ -632,6 +643,33 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor
632643
removed.forEach(viewDescriptor => this.getOrCreateActiveViewContextKey(viewDescriptor).set(false));
633644
}
634645

646+
private registerResetViewContainerAction(viewContainer: ViewContainer): IDisposable {
647+
const that = this;
648+
return registerAction2(class ResetViewLocationAction extends Action2 {
649+
constructor() {
650+
super({
651+
id: `${viewContainer.id}.resetViewContainerLocation`,
652+
title: {
653+
original: 'Reset Location',
654+
value: localize('resetViewLocation', "Reset Location")
655+
},
656+
menu: [{
657+
id: MenuId.ViewContainerTitleContext,
658+
when: ContextKeyExpr.or(
659+
ContextKeyExpr.and(
660+
ContextKeyExpr.equals('container', viewContainer.id),
661+
ContextKeyExpr.equals(`${viewContainer.id}.defaultViewContainerLocation`, false)
662+
)
663+
)
664+
}],
665+
});
666+
}
667+
run(): void {
668+
that.moveViewContainerToLocation(viewContainer, that.getDefaultViewContainerLocation(viewContainer));
669+
}
670+
});
671+
}
672+
635673
private addViews(container: ViewContainer, views: IViewDescriptor[]): void {
636674
// Update in memory cache
637675
views.forEach(view => {
@@ -679,6 +717,16 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor
679717
}
680718
return contextKey;
681719
}
720+
721+
private getOrCreateDefaultViewContainerLocationContextKey(viewContainer: ViewContainer): IContextKey<boolean> {
722+
const defaultViewContainerLocationContextKeyId = `${viewContainer.id}.defaultViewContainerLocation`;
723+
let contextKey = this.defaultViewContainerLocationContextKeys.get(defaultViewContainerLocationContextKeyId);
724+
if (!contextKey) {
725+
contextKey = new RawContextKey(defaultViewContainerLocationContextKeyId, false).bindTo(this.contextKeyService);
726+
this.defaultViewContainerLocationContextKeys.set(defaultViewContainerLocationContextKeyId, contextKey);
727+
}
728+
return contextKey;
729+
}
682730
}
683731

684732
registerSingleton(IViewDescriptorService, ViewDescriptorService);

0 commit comments

Comments
 (0)