提交 2175d4c0 编写于 作者: S Sandeep Somavarapu

- Introduce menu id to contribute view title context menu actions

- Use this menu id to get context menu action for a view
上级 1cc556a9
......@@ -104,6 +104,7 @@ export const enum MenuId {
TunnelTitle,
ViewItemContext,
ViewTitle,
ViewTitleContext,
CommentThreadTitle,
CommentThreadActions,
CommentTitle,
......
......@@ -125,6 +125,7 @@ export class ActivitybarPart extends Part implements IActivityBarService {
actions.push(this.instantiationService.createInstance(ToggleActivityBarVisibilityAction, ToggleActivityBarVisibilityAction.ID, nls.localize('hideActivitBar', "Hide Activity Bar")));
return actions;
},
getContextMenuActionsForComposite: () => [],
getDefaultCompositeId: () => this.viewletService.getDefaultViewletId(),
hidePart: () => this.layoutService.setSideBarHidden(true),
compositeSize: 50,
......
......@@ -40,7 +40,7 @@ export interface ICompositeBarOptions {
getCompositePinnedAction: (compositeId: string) => Action;
getOnCompositeClickAction: (compositeId: string) => Action;
getContextMenuActions: () => Action[];
getContextMenuActionsForCompositeId?: (compositeId: string) => Action[];
getContextMenuActionsForComposite: (compositeId: string) => Action[];
openComposite: (compositeId: string) => Promise<any>;
getDefaultCompositeId: () => string;
hidePart: () => void;
......@@ -103,7 +103,7 @@ export class CompositeBar extends Widget implements ICompositeBar {
const item = this.model.findItem(action.id);
return item && this.instantiationService.createInstance(
CompositeActionViewItem, action as ActivityAction, item.pinnedAction,
(compositeId: string) => { return this.options.getContextMenuActionsForCompositeId === undefined ? [] : this.options.getContextMenuActionsForCompositeId(compositeId); },
(compositeId: string) => this.options.getContextMenuActionsForComposite(compositeId),
() => this.getContextMenuActions() as Action[],
this.options.colors,
this.options.icon,
......
......@@ -463,7 +463,7 @@ export class CompositeActionViewItem extends ActivityActionViewItem {
constructor(
private compositeActivityAction: ActivityAction,
private toggleCompositePinnedAction: Action,
private compositeMenuActionsProvider: (compositeId: string) => ReadonlyArray<Action>,
private compositeContextMenuActionsProvider: (compositeId: string) => ReadonlyArray<Action>,
private contextMenuActionsProvider: () => ReadonlyArray<Action>,
colors: (theme: ITheme) => ICompositeBarColors,
icon: boolean,
......@@ -598,9 +598,9 @@ export class CompositeActionViewItem extends ActivityActionViewItem {
private showContextMenu(container: HTMLElement): void {
const actions: Action[] = [this.toggleCompositePinnedAction];
const compositeSpecificActions = this.compositeMenuActionsProvider(this.activity.id);
if (compositeSpecificActions.length) {
actions.push(...compositeSpecificActions);
const compositeContextMenuActions = this.compositeContextMenuActionsProvider(this.activity.id);
if (compositeContextMenuActions.length) {
actions.push(...compositeContextMenuActions);
}
if ((<any>this.compositeActivityAction.activity).extensionId) {
......
......@@ -34,6 +34,8 @@ import { isUndefinedOrNull, assertIsDefined } from 'vs/base/common/types';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
import { ViewContainer, IViewContainersRegistry, Extensions as ViewContainerExtensions, IViewDescriptorService, IViewDescriptorCollection } from 'vs/workbench/common/views';
import { MenuId } from 'vs/platform/actions/common/actions';
import { ViewMenuActions } from 'vs/workbench/browser/parts/views/viewMenuActions';
interface ICachedPanel {
id: string;
......@@ -137,7 +139,7 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
.map(({ id, label }) => this.instantiationService.createInstance(SetPanelPositionAction, id, label)),
this.instantiationService.createInstance(TogglePanelAction, TogglePanelAction.ID, localize('hidePanel', "Hide Panel"))
] as Action[],
getContextMenuActionsForCompositeId: (compositeId: string) => this.getContextMenuActionsForCompositeId(compositeId) as Action[],
getContextMenuActionsForComposite: (compositeId: string) => this.getContextMenuActionsForComposite(compositeId) as Action[],
getDefaultCompositeId: () => this.panelRegistry.getDefaultPanelId(),
hidePart: () => this.layoutService.setPanelHidden(true),
compositeSize: 0,
......@@ -161,14 +163,18 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
this.onDidRegisterPanels([...this.getPanels()]);
}
private getContextMenuActionsForCompositeId(compositeId: string): readonly IAction[] {
const panel = this.getActivePanel();
if (!panel || panel.getId() !== compositeId) {
return [];
private getContextMenuActionsForComposite(compositeId: string): readonly IAction[] {
const result: IAction[] = [];
const container = this.getViewContainer(compositeId);
if (container) {
const viewDescriptors = this.viewDescriptorService.getViewDescriptors(container);
if (viewDescriptors.allViewDescriptors.length === 1) {
const viewMenuActions = this.instantiationService.createInstance(ViewMenuActions, viewDescriptors.allViewDescriptors[0].id, MenuId.ViewTitle, MenuId.ViewTitleContext);
result.push(...viewMenuActions.getContextMenuActions());
viewMenuActions.dispose();
}
}
return panel.getContextMenuActions();
return result;
}
private onDidRegisterPanels(panels: PanelDescriptor[]): void {
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IAction } from 'vs/base/common/actions';
import { Disposable, MutableDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { Emitter, Event } from 'vs/base/common/event';
import { MenuId, IMenuService } from 'vs/platform/actions/common/actions';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { createAndFillInActionBarActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
export class ViewMenuActions extends Disposable {
private primaryActions: IAction[] = [];
private readonly titleActionsDisposable = this._register(new MutableDisposable());
private secondaryActions: IAction[] = [];
private contextMenuActions: IAction[] = [];
private _onDidChangeTitle = this._register(new Emitter<void>());
readonly onDidChangeTitle: Event<void> = this._onDidChangeTitle.event;
constructor(
viewId: string,
menuId: MenuId,
contextMenuId: MenuId,
@IContextKeyService private readonly contextKeyService: IContextKeyService,
@IMenuService private readonly menuService: IMenuService,
) {
super();
const scopedContextKeyService = this._register(this.contextKeyService.createScoped());
scopedContextKeyService.createKey('view', viewId);
const menu = this._register(this.menuService.createMenu(menuId, scopedContextKeyService));
const updateActions = () => {
this.primaryActions = [];
this.secondaryActions = [];
this.titleActionsDisposable.value = createAndFillInActionBarActions(menu, undefined, { primary: this.primaryActions, secondary: this.secondaryActions });
this._onDidChangeTitle.fire();
};
this._register(menu.onDidChange(updateActions));
updateActions();
const contextMenu = this._register(this.menuService.createMenu(contextMenuId, scopedContextKeyService));
const updateContextMenuActions = () => {
this.contextMenuActions = [];
this.titleActionsDisposable.value = createAndFillInActionBarActions(contextMenu, undefined, { primary: [], secondary: this.contextMenuActions });
};
this._register(contextMenu.onDidChange(updateContextMenuActions));
updateContextMenuActions();
this._register(toDisposable(() => {
this.primaryActions = [];
this.secondaryActions = [];
this.contextMenuActions = [];
}));
}
getPrimaryActions(): IAction[] {
return this.primaryActions;
}
getSecondaryActions(): IAction[] {
return this.secondaryActions;
}
getContextMenuActions(): IAction[] {
return this.contextMenuActions;
}
}
......@@ -10,7 +10,7 @@ import { ColorIdentifier } from 'vs/platform/theme/common/colorRegistry';
import { attachStyler, IColorMapping } from 'vs/platform/theme/common/styler';
import { SIDE_BAR_DRAG_AND_DROP_BACKGROUND, SIDE_BAR_SECTION_HEADER_FOREGROUND, SIDE_BAR_SECTION_HEADER_BACKGROUND, SIDE_BAR_SECTION_HEADER_BORDER } from 'vs/workbench/common/theme';
import { append, $, trackFocus, toggleClass, EventType, isAncestor, Dimension, addDisposableListener } from 'vs/base/browser/dom';
import { IDisposable, combinedDisposable, dispose, toDisposable, Disposable, MutableDisposable } from 'vs/base/common/lifecycle';
import { IDisposable, combinedDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle';
import { firstIndex } from 'vs/base/common/arrays';
import { IAction, IActionRunner, ActionRunner } from 'vs/base/common/actions';
import { IActionViewItem, ActionsOrientation, Separator } from 'vs/base/browser/ui/actionbar/actionbar';
......@@ -25,7 +25,7 @@ import { PaneView, IPaneViewOptions, IPaneOptions, Pane, DefaultPaneDndControlle
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
import { Extensions as ViewContainerExtensions, IView, FocusedViewContext, IViewContainersRegistry, IViewDescriptor, ViewContainer, IViewDescriptorService, Extensions as ViewsExtensions, ViewContainerLocation, IViewsService, IViewsRegistry } from 'vs/workbench/common/views';
import { Extensions as ViewContainerExtensions, IView, FocusedViewContext, IViewContainersRegistry, IViewDescriptor, ViewContainer, IViewDescriptorService, ViewContainerLocation, IViewsService } from 'vs/workbench/common/views';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { assertIsDefined } from 'vs/base/common/types';
......@@ -36,8 +36,9 @@ import { IExtensionService } from 'vs/workbench/services/extensions/common/exten
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { IViewPaneContainer } from 'vs/workbench/common/viewPaneContainer';
import { Component } from 'vs/workbench/common/component';
import { IMenuService, MenuId, MenuItemAction } from 'vs/platform/actions/common/actions';
import { createAndFillInActionBarActions, ContextAwareMenuEntryActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { MenuId, MenuItemAction } from 'vs/platform/actions/common/actions';
import { ContextAwareMenuEntryActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { ViewMenuActions } from 'vs/workbench/browser/parts/views/viewMenuActions';
export interface IPaneColors extends IColorMapping {
dropBackground?: ColorIdentifier;
......@@ -76,7 +77,7 @@ export abstract class ViewPane extends Pane implements IView {
readonly id: string;
title: string;
private readonly menuActions?: ViewMenuActions;
private readonly menuActions: ViewMenuActions;
protected actionRunner?: IActionRunner;
protected toolbar?: ToolBar;
......@@ -101,10 +102,8 @@ export abstract class ViewPane extends Pane implements IView {
this.showActionsAlways = !!options.showActionsAlways;
this.focusedViewContextKey = FocusedViewContext.bindTo(contextKeyService);
if (options.titleMenuId !== undefined) {
this.menuActions = this._register(instantiationService.createInstance(ViewMenuActions, this.id, options.titleMenuId));
this._register(this.menuActions.onDidChangeTitle(() => this.updateActions()));
}
this.menuActions = this._register(instantiationService.createInstance(ViewMenuActions, this.id, options.titleMenuId || MenuId.ViewTitle, MenuId.ViewTitleContext));
this._register(this.menuActions.onDidChangeTitle(() => this.updateActions()));
}
setVisible(visible: boolean): void {
......@@ -225,6 +224,10 @@ export abstract class ViewPane extends Pane implements IView {
return this.menuActions ? this.menuActions.getSecondaryActions() : [];
}
getContextMenuActions(): IAction[] {
return this.menuActions ? this.menuActions.getContextMenuActions() : [];
}
getActionViewItem(action: IAction): IActionViewItem | undefined {
if (action instanceof MenuItemAction) {
return this.instantiationService.createInstance(ContextAwareMenuEntryActionViewItem, action);
......@@ -391,55 +394,39 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer {
}
getContextMenuActions(viewDescriptor?: IViewDescriptor): IAction[] {
const result: IAction[] = [];
if (this.isViewMergedWithContainer()) {
const viewId = this.panes[0].id;
viewDescriptor = Registry.as<IViewsRegistry>(ViewsExtensions.ViewsRegistry).getView(viewId)!;
if (!viewDescriptor && this.isViewMergedWithContainer()) {
viewDescriptor = this.viewDescriptorService.getViewDescriptor(this.panes[0].id) || undefined;
}
const viewContainerRegistry = Registry.as<IViewContainersRegistry>(ViewsExtensions.ViewContainersRegistry);
const currentLocation = viewContainerRegistry.getViewContainerLocation(this.viewContainer);
const result: IAction[] = [];
if (viewDescriptor) {
// For now, restrict any additional actions to the sidebar only
if (!this.isViewMergedWithContainer() && currentLocation === ViewContainerLocation.Sidebar) {
result.push(<IAction>{
id: `${viewDescriptor.id}.removeView`,
label: nls.localize('hideView', "Hide"),
enabled: viewDescriptor.canToggleVisibility,
run: () => this.toggleViewVisibility(viewDescriptor!.id)
});
}
if (viewDescriptor.canMoveView) {
const newLocation = currentLocation === ViewContainerLocation.Panel ? ViewContainerLocation.Sidebar : ViewContainerLocation.Panel;
result.push(<IAction>{
id: `${viewDescriptor.id}.moveView`,
label: newLocation === ViewContainerLocation.Sidebar ? nls.localize('moveViewToSidebar', "Move to Sidebar") : nls.localize('moveViewToPanel', "Move to Panel"),
enabled: true,
run: () => this.moveView(viewDescriptor!, newLocation)
});
result.push(<IAction>{
id: `${viewDescriptor.id}.removeView`,
label: nls.localize('hideView', "Hide"),
enabled: viewDescriptor.canToggleVisibility,
run: () => this.toggleViewVisibility(viewDescriptor!.id)
});
const view = this.getView(viewDescriptor.id);
if (view) {
result.push(...view.getContextMenuActions());
}
}
// For now, restrict any additional actions to the sidebar only
if (currentLocation === ViewContainerLocation.Sidebar) {
const viewToggleActions = this.viewsModel.viewDescriptors.map(viewDescriptor => (<IAction>{
id: `${viewDescriptor.id}.toggleVisibility`,
label: viewDescriptor.name,
checked: this.viewsModel.isVisible(viewDescriptor.id),
enabled: viewDescriptor.canToggleVisibility,
run: () => this.toggleViewVisibility(viewDescriptor.id)
}));
if (result.length && viewToggleActions.length) {
result.push(new Separator());
}
const viewToggleActions = this.viewsModel.viewDescriptors.map(viewDescriptor => (<IAction>{
id: `${viewDescriptor.id}.toggleVisibility`,
label: viewDescriptor.name,
checked: this.viewsModel.isVisible(viewDescriptor.id),
enabled: viewDescriptor.canToggleVisibility,
run: () => this.toggleViewVisibility(viewDescriptor.id)
}));
result.push(...viewToggleActions);
if (result.length && viewToggleActions.length) {
result.push(new Separator());
}
result.push(...viewToggleActions);
return result;
}
......@@ -803,50 +790,3 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer {
}
}
}
class ViewMenuActions extends Disposable {
private primaryActions: IAction[] = [];
private readonly titleActionsDisposable = this._register(new MutableDisposable());
private secondaryActions: IAction[] = [];
private _onDidChangeTitle = this._register(new Emitter<void>());
readonly onDidChangeTitle: Event<void> = this._onDidChangeTitle.event;
constructor(
viewId: string,
menuId: MenuId,
@IContextKeyService private readonly contextKeyService: IContextKeyService,
@IMenuService private readonly menuService: IMenuService,
) {
super();
const scopedContextKeyService = this._register(this.contextKeyService.createScoped());
scopedContextKeyService.createKey('view', viewId);
const menu = this._register(this.menuService.createMenu(menuId, scopedContextKeyService));
const updateActions = () => {
this.primaryActions = [];
this.secondaryActions = [];
this.titleActionsDisposable.value = createAndFillInActionBarActions(menu, undefined, { primary: this.primaryActions, secondary: this.secondaryActions });
this._onDidChangeTitle.fire();
};
this._register(menu.onDidChange(updateActions));
updateActions();
this._register(toDisposable(() => {
this.primaryActions = [];
this.secondaryActions = [];
}));
}
getPrimaryActions(): IAction[] {
return this.primaryActions;
}
getSecondaryActions(): IAction[] {
return this.secondaryActions;
}
}
......@@ -13,18 +13,16 @@ import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { Event, Emitter } from 'vs/base/common/event';
import { firstIndex, move } from 'vs/base/common/arrays';
import { isUndefinedOrNull, isUndefined } from 'vs/base/common/types';
import { MenuId, MenuRegistry, ICommandAction } from 'vs/platform/actions/common/actions';
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
import { MenuId, registerAction2, Action2 } from 'vs/platform/actions/common/actions';
import { localize } from 'vs/nls';
import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { values } from 'vs/base/common/map';
import { IFileIconTheme, IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
import { toggleClass, addClass } from 'vs/base/browser/dom';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { IPaneComposite } from 'vs/workbench/common/panecomposite';
import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
import type { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
export interface IViewState {
visibleGlobal: boolean | undefined;
......@@ -472,14 +470,14 @@ export class ViewsService extends Disposable implements IViewsService {
private onViewContainerRegistered(viewContainer: ViewContainer): void {
const viewDescriptorCollection = this.viewDescriptorService.getViewDescriptors(viewContainer);
this.onViewsRegistered(viewDescriptorCollection.allViewDescriptors, viewContainer);
this.onViewsAdded(viewDescriptorCollection.allViewDescriptors, viewContainer);
this._register(viewDescriptorCollection.onDidChangeViews(({ added, removed }) => {
this.onViewsRegistered(added, viewContainer);
this.onViewsDeregistered(removed);
this.onViewsAdded(added, viewContainer);
this.onViewsRemoved(removed);
}));
}
private onViewsRegistered(views: IViewDescriptor[], container: ViewContainer): void {
private onViewsAdded(views: IViewDescriptor[], container: ViewContainer): void {
const location = this.viewContainersRegistry.getViewContainerLocation(container);
if (location === undefined) {
return;
......@@ -488,38 +486,57 @@ export class ViewsService extends Disposable implements IViewsService {
const composite = this.getComposite(container.id, location);
for (const viewDescriptor of views) {
const disposables = new DisposableStore();
const command: ICommandAction = {
id: viewDescriptor.focusCommand ? viewDescriptor.focusCommand.id : `${viewDescriptor.id}.focus`,
title: { original: `Focus on ${viewDescriptor.name} View`, value: localize('focus view', "Focus on {0} View", viewDescriptor.name) },
category: composite ? composite.name : localize('view category', "View"),
};
const when = ContextKeyExpr.has(`${viewDescriptor.id}.active`);
disposables.add(CommandsRegistry.registerCommand(command.id, () => this.openView(viewDescriptor.id, true)));
disposables.add(MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
command,
when
disposables.add(registerAction2(class FocusViewAction extends Action2 {
constructor() {
super({
id: viewDescriptor.focusCommand ? viewDescriptor.focusCommand.id : `${viewDescriptor.id}.focus`,
title: { original: `Focus on ${viewDescriptor.name} View`, value: localize('focus view', "Focus on {0} View", viewDescriptor.name) },
category: composite ? composite.name : localize('view category', "View"),
menu: [{
id: MenuId.CommandPalette,
}],
keybinding: {
when: ContextKeyExpr.has(`${viewDescriptor.id}.active`),
weight: KeybindingWeight.WorkbenchContrib,
primary: viewDescriptor.focusCommand?.keybindings?.primary,
secondary: viewDescriptor.focusCommand?.keybindings?.secondary,
linux: viewDescriptor.focusCommand?.keybindings?.linux,
mac: viewDescriptor.focusCommand?.keybindings?.mac,
win: viewDescriptor.focusCommand?.keybindings?.win
}
});
}
run(accessor: ServicesAccessor): any {
accessor.get(IViewsService).openView(viewDescriptor.id, true);
}
}));
if (viewDescriptor.focusCommand && viewDescriptor.focusCommand.keybindings) {
KeybindingsRegistry.registerKeybindingRule({
id: command.id,
when,
weight: KeybindingWeight.WorkbenchContrib,
primary: viewDescriptor.focusCommand.keybindings.primary,
secondary: viewDescriptor.focusCommand.keybindings.secondary,
linux: viewDescriptor.focusCommand.keybindings.linux,
mac: viewDescriptor.focusCommand.keybindings.mac,
win: viewDescriptor.focusCommand.keybindings.win
});
}
const newLocation = location === ViewContainerLocation.Panel ? ViewContainerLocation.Sidebar : ViewContainerLocation.Panel;
disposables.add(registerAction2(class MoveViewAction extends Action2 {
constructor() {
super({
id: `${viewDescriptor.id}.moveView`,
title: {
original: newLocation === ViewContainerLocation.Sidebar ? 'Move to Sidebar' : 'Move to Panel',
value: newLocation === ViewContainerLocation.Sidebar ? localize('moveViewToSidebar', "Move to Sidebar") : localize('moveViewToPanel', "Move to Panel")
},
menu: [{
id: MenuId.ViewTitleContext,
when: ContextKeyExpr.and(ContextKeyExpr.equals('view', viewDescriptor.id), ContextKeyExpr.has(`${viewDescriptor.id}.canMove`)),
}],
});
}
run(accessor: ServicesAccessor): any {
accessor.get(IViewDescriptorService).moveViewToLocation(viewDescriptor, newLocation);
accessor.get(IViewsService).openView(viewDescriptor.id);
}
}));
this.viewDisposable.set(viewDescriptor, disposables);
}
}
private onViewsDeregistered(views: IViewDescriptor[]): void {
private onViewsRemoved(views: IViewDescriptor[]): void {
for (const view of views) {
const disposable = this.viewDisposable.get(view);
if (disposable) {
......
......@@ -371,6 +371,8 @@ export interface IViewDescriptorService {
getViewDescriptors(container: ViewContainer): IViewDescriptorCollection;
getViewDescriptor(viewId: string): IViewDescriptor | null;
getViewContainer(viewId: string): ViewContainer | null;
getDefaultContainer(viewId: string): ViewContainer | null;
......
......@@ -183,6 +183,7 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor
private readonly viewDescriptorCollections: Map<ViewContainer, { viewDescriptorCollection: ViewDescriptorCollection, disposable: IDisposable; }>;
private readonly activeViewContextKeys: Map<string, IContextKey<boolean>>;
private readonly movableViewContextKeys: Map<string, IContextKey<boolean>>;
private readonly viewsRegistry: IViewsRegistry;
private readonly viewContainersRegistry: IViewContainersRegistry;
......@@ -215,6 +216,7 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor
this.viewDescriptorCollections = new Map<ViewContainer, { viewDescriptorCollection: ViewDescriptorCollection, disposable: IDisposable; }>();
this.activeViewContextKeys = new Map<string, IContextKey<boolean>>();
this.movableViewContextKeys = new Map<string, IContextKey<boolean>>();
this.viewContainersRegistry = Registry.as<IViewContainersRegistry>(ViewExtensions.ViewContainersRegistry);
this.viewsRegistry = Registry.as<IViewsRegistry>(ViewExtensions.ViewsRegistry);
......@@ -280,7 +282,7 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor
// check if we should generate this container
if (containerInfo.sourceViewId && containerInfo.location !== undefined) {
const sourceView = this.viewsRegistry.getView(containerInfo.sourceViewId);
const sourceView = this.getViewDescriptor(containerInfo.sourceViewId);
if (sourceView) {
this.registerViewContainerForSingleView(sourceView, containerInfo.location);
......@@ -290,7 +292,7 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor
// check if view has been registered to default location
const viewContainer = this.viewsRegistry.getViewContainer(viewId);
const viewDescriptor = this.viewsRegistry.getView(viewId);
const viewDescriptor = this.getViewDescriptor(viewId);
if (viewContainer && viewDescriptor) {
this.addViews(viewContainer, [viewDescriptor]);
}
......@@ -306,12 +308,15 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor
// Once they are grouped, try registering them which occurs
// if the container has already been registered within this service
this.registerGroupedViews(regroupedViews);
views.forEach(viewDescriptor => this.getOrCreateMovableViewContextKey(viewDescriptor).set(!!viewDescriptor.canMoveView));
}
private onDidDeregisterViews(views: IViewDescriptor[], viewContainer: ViewContainer): void {
// When views are registered, we need to regroup them based on the cache
const regroupedViews = this.regroupViews(viewContainer.id, views);
this.deregisterGroupedViews(regroupedViews);
views.forEach(viewDescriptor => this.getOrCreateMovableViewContextKey(viewDescriptor).set(false));
}
private regroupViews(containerId: string, views: IViewDescriptor[]): Map<string, IViewDescriptor[]> {
......@@ -328,6 +333,10 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor
return ret;
}
getViewDescriptor(viewId: string): IViewDescriptor | null {
return this.viewsRegistry.getView(viewId);
}
getViewContainer(viewId: string): ViewContainer | null {
const containerId = this.cachedViewInfo.get(viewId)?.containerId;
return containerId ?
......@@ -408,7 +417,7 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor
const prevViewContainer = this.getViewContainer(viewId);
const newViewContainer = this.viewContainersRegistry.get(newCachedPositions.get(viewId)!.containerId);
if (prevViewContainer && newViewContainer && newViewContainer !== prevViewContainer) {
const viewDescriptor = this.viewsRegistry.getView(viewId);
const viewDescriptor = this.getViewDescriptor(viewId);
if (viewDescriptor) {
// We don't call move views to avoid sending intermediate
// cached data to the window that gave us this information
......@@ -470,7 +479,7 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor
continue;
}
const viewDescriptor = this.viewsRegistry.getView(viewId);
const viewDescriptor = this.getViewDescriptor(viewId);
if (viewDescriptor) {
result.push(viewDescriptor);
}
......@@ -498,6 +507,7 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor
const viewsToRegister = this.getViewsByContainer(viewContainer);
if (viewsToRegister.length) {
this.addViews(viewContainer, viewsToRegister);
viewsToRegister.forEach(viewDescriptor => this.getOrCreateMovableViewContextKey(viewDescriptor).set(!!viewDescriptor.canMoveView));
}
}
......@@ -522,8 +532,7 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor
}
private removeViews(container: ViewContainer, views: IViewDescriptor[]): void {
const viewDescriptorCollection = this.getViewDescriptors(container);
viewDescriptorCollection.removeViews(views);
this.getViewDescriptors(container).removeViews(views);
}
private getOrCreateActiveViewContextKey(viewDescriptor: IViewDescriptor): IContextKey<boolean> {
......@@ -535,6 +544,16 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor
}
return contextKey;
}
private getOrCreateMovableViewContextKey(viewDescriptor: IViewDescriptor): IContextKey<boolean> {
const movableViewContextKeyId = `${viewDescriptor.id}.canMove`;
let contextKey = this.movableViewContextKeys.get(movableViewContextKeyId);
if (!contextKey) {
contextKey = new RawContextKey(movableViewContextKeyId, false).bindTo(this.contextKeyService);
this.movableViewContextKeys.set(movableViewContextKeyId, contextKey);
}
return contextKey;
}
}
registerSingleton(IViewDescriptorService, ViewDescriptorService);
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册