diff options
Diffstat (limited to 'src/vs/platform/actions/common/actions.ts')
-rw-r--r-- | src/vs/platform/actions/common/actions.ts | 56 |
1 files changed, 49 insertions, 7 deletions
diff --git a/src/vs/platform/actions/common/actions.ts b/src/vs/platform/actions/common/actions.ts index d1cd1197cce..461df3221c1 100644 --- a/src/vs/platform/actions/common/actions.ts +++ b/src/vs/platform/actions/common/actions.ts @@ -45,7 +45,7 @@ export function isISubmenuItem(item: IMenuItem | ISubmenuItem): item is ISubmenu export class MenuId { - private static _idPool = 0; + private static readonly _instances = new Map<string, MenuId>(); static readonly CommandPalette = new MenuId('CommandPalette'); static readonly DebugBreakpointsContext = new MenuId('DebugBreakpointsContext'); @@ -162,12 +162,26 @@ export class MenuId { static readonly NewFile = new MenuId('NewFile'); static readonly MergeToolbar = new MenuId('MergeToolbar'); - readonly id: number; - readonly _debugName: string; + /** + * Create or reuse a `MenuId` with the given identifier + */ + static for(identifier: string): MenuId { + return MenuId._instances.get(identifier) ?? new MenuId(identifier); + } + + readonly id: string; - constructor(debugName: string) { - this.id = MenuId._idPool++; - this._debugName = debugName; + /** + * Create a new `MenuId` with the unique identifier. Will throw if a menu + * with the identifier already exists, use `MenuId.for(ident)` or a unique + * identifier + */ + constructor(identifier: string) { + if (MenuId._instances.has(identifier)) { + throw new TypeError(`MenuId with identifier '${identifier}' already exists. Use MenuId.for(ident) or a unique identifier`); + } + MenuId._instances.set(identifier, this); + this.id = identifier; } } @@ -193,7 +207,18 @@ export interface IMenuService { readonly _serviceBrand: undefined; + /** + * Create a new menu for the given menu identifier. A menu sends events when it's entries + * have changed (placement, enablement, checked-state). By default it does not send events for + * submenu entries. That is more expensive and must be explicitly enabled with the + * `emitEventsForSubmenuChanges` flag. + */ createMenu(id: MenuId, contextKeyService: IContextKeyService, options?: IMenuCreateOptions): IMenu; + + /** + * Reset **all** menu item hidden states. + */ + resetHiddenStates(): void; } export type ICommandsMap = Map<string, ICommandAction>; @@ -350,6 +375,22 @@ export class SubmenuItemAction extends SubmenuAction { } } +export class MenuItemActionManageActions { + constructor( + readonly hideThis: IAction, + readonly toggleAny: readonly IAction[][], + ) { } + + asList(): IAction[] { + let result: IAction[] = [this.hideThis]; + for (const n of this.toggleAny) { + result.push(new Separator()); + result = result.concat(n); + } + return result; + } +} + // implements IAction, does NOT extend Action, so that no one // subscribes to events of Action or modified properties export class MenuItemAction implements IAction { @@ -370,6 +411,7 @@ export class MenuItemAction implements IAction { item: ICommandAction, alt: ICommandAction | undefined, options: IMenuActionOptions | undefined, + readonly hideActions: MenuItemActionManageActions | undefined, @IContextKeyService contextKeyService: IContextKeyService, @ICommandService private _commandService: ICommandService ) { @@ -396,7 +438,7 @@ export class MenuItemAction implements IAction { } this.item = item; - this.alt = alt ? new MenuItemAction(alt, undefined, options, contextKeyService, _commandService) : undefined; + this.alt = alt ? new MenuItemAction(alt, undefined, options, hideActions, contextKeyService, _commandService) : undefined; this._options = options; if (ThemeIcon.isThemeIcon(item.icon)) { this.class = CSSIcon.asClassName(item.icon); |