From 07926e59b848fb6fc1a63359035d283fd76689d7 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 15 Jun 2016 10:53:59 +0200 Subject: [PATCH] shared context menu for title controls --- .../parts/editor/noTabsTitleControl.ts | 7 +- .../browser/parts/editor/tabsTitleControl.ts | 66 ++--------------- .../browser/parts/editor/titleControl.ts | 70 ++++++++++++++++++- 3 files changed, 81 insertions(+), 62 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/noTabsTitleControl.ts b/src/vs/workbench/browser/parts/editor/noTabsTitleControl.ts index c5ec12ea615..8c28051c36e 100644 --- a/src/vs/workbench/browser/parts/editor/noTabsTitleControl.ts +++ b/src/vs/workbench/browser/parts/editor/noTabsTitleControl.ts @@ -16,6 +16,7 @@ import {ToolBar} from 'vs/base/browser/ui/toolbar/toolbar'; import {IWorkbenchEditorService} from 'vs/workbench/services/editor/common/editorService'; import {IContextMenuService} from 'vs/platform/contextview/browser/contextView'; import {IEditorGroupService} from 'vs/workbench/services/group/common/groupService'; +import {IConfigurationService} from 'vs/platform/configuration/common/configuration'; import {IMessageService} from 'vs/platform/message/common/message'; import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry'; import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation'; @@ -36,13 +37,14 @@ export class NoTabsTitleControl extends TitleControl { constructor( @IContextMenuService contextMenuService: IContextMenuService, @IInstantiationService instantiationService: IInstantiationService, + @IConfigurationService configurationService: IConfigurationService, @IWorkbenchEditorService editorService: IWorkbenchEditorService, @IEditorGroupService editorGroupService: IEditorGroupService, @IKeybindingService keybindingService: IKeybindingService, @ITelemetryService telemetryService: ITelemetryService, @IMessageService messageService: IMessageService ) { - super(contextMenuService, instantiationService, editorService, editorGroupService, keybindingService, telemetryService, messageService); + super(contextMenuService, instantiationService, configurationService, editorService, editorGroupService, keybindingService, telemetryService, messageService); this.currentPrimaryEditorActionIds = []; this.currentSecondaryEditorActionIds = []; @@ -98,6 +100,9 @@ export class NoTabsTitleControl extends TitleControl { // Editor actions this.editorActionsToolbar = this.doCreateToolbar(div); }); + + // Context Menu + this.titleContainer.on(DOM.EventType.CONTEXT_MENU, (e: Event) => this.onContextMenu({ group: this.context, editor: this.context.activeEditor }, e, this.titleContainer.getHTMLElement())); } private onTitleDoubleClick(): void { diff --git a/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts b/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts index a1bde64cb34..6e2612c7270 100644 --- a/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts +++ b/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts @@ -6,7 +6,6 @@ 'use strict'; import 'vs/css!./media/tabstitle'; -import {TPromise} from 'vs/base/common/winjs.base'; import nls = require('vs/nls'); import {IAction} from 'vs/base/common/actions'; import {prepareActions} from 'vs/workbench/browser/actionBarRegistry'; @@ -18,12 +17,11 @@ import {isMacintosh} from 'vs/base/common/platform'; import {Builder, $} from 'vs/base/browser/builder'; import {MIME_BINARY} from 'vs/base/common/mime'; import {Position} from 'vs/platform/editor/common/editor'; -import {IEditorGroup, IEditorIdentifier, asFileEditorInput, EditorOptions, IWorkbenchEditorConfiguration} from 'vs/workbench/common/editor'; +import {IEditorGroup, IEditorIdentifier, asFileEditorInput, EditorOptions} from 'vs/workbench/common/editor'; import {ToolBar} from 'vs/base/browser/ui/toolbar/toolbar'; import {StandardKeyboardEvent} from 'vs/base/browser/keyboardEvent'; import {CommonKeybindings as Kb} from 'vs/base/common/keyCodes'; import {ActionBar, Separator} from 'vs/base/browser/ui/actionbar/actionbar'; -import {StandardMouseEvent} from 'vs/base/browser/mouseEvent'; import {IConfigurationService} from 'vs/platform/configuration/common/configuration'; import {IWorkbenchEditorService} from 'vs/workbench/services/editor/common/editorService'; import {IContextMenuService} from 'vs/platform/contextview/browser/contextView'; @@ -52,36 +50,22 @@ export class TabsTitleControl extends TitleControl { private currentPrimaryGroupActionIds: string[]; private currentSecondaryGroupActionIds: string[]; - private previewEditors: boolean; - constructor( @IContextMenuService contextMenuService: IContextMenuService, @IInstantiationService instantiationService: IInstantiationService, - @IConfigurationService private configurationService: IConfigurationService, + @IConfigurationService configurationService: IConfigurationService, @IWorkbenchEditorService editorService: IWorkbenchEditorService, @IEditorGroupService editorGroupService: IEditorGroupService, @IKeybindingService keybindingService: IKeybindingService, @ITelemetryService telemetryService: ITelemetryService, @IMessageService messageService: IMessageService ) { - super(contextMenuService, instantiationService, editorService, editorGroupService, keybindingService, telemetryService, messageService); + super(contextMenuService, instantiationService, configurationService, editorService, editorGroupService, keybindingService, telemetryService, messageService); this.currentPrimaryGroupActionIds = []; this.currentSecondaryGroupActionIds = []; this.tabDisposeables = []; - - this.onConfigurationUpdated(configurationService.getConfiguration()); - - this.registerListeners(); - } - - private registerListeners(): void { - this.toDispose.push(this.configurationService.onDidUpdateConfiguration(e => this.onConfigurationUpdated(e.config))); - } - - private onConfigurationUpdated(config: IWorkbenchEditorConfiguration): void { - this.previewEditors = config.workbench.previewEditors; } public setContext(group: IEditorGroup): void { @@ -425,29 +409,7 @@ export class TabsTitleControl extends TitleControl { })); // Context menu - this.tabDisposeables.push(DOM.addDisposableListener(tab, DOM.EventType.CONTEXT_MENU, (e: Event) => { - DOM.EventHelper.stop(e); - - let anchor: HTMLElement | { x: number, y: number } = tab; - if (e instanceof MouseEvent) { - const event = new StandardMouseEvent(e); - anchor = { x: event.posx, y: event.posy }; - } - - this.contextMenuService.showContextMenu({ - getAnchor: () => anchor, - getActions: () => TPromise.as(this.getTabActions(identifier)), - getActionsContext: () => identifier, - getKeyBinding: (action) => { - var opts = this.keybindingService.lookupKeybindings(action.id); - if (opts.length > 0) { - return opts[0]; // only take the first one - } - - return null; - } - }); - })); + this.tabDisposeables.push(DOM.addDisposableListener(tab, DOM.EventType.CONTEXT_MENU, (e: Event) => this.onContextMenu(identifier, e, tab))); // Drag start this.tabDisposeables.push(DOM.addDisposableListener(tab, DOM.EventType.DRAG_START, (e: DragEvent) => { @@ -557,26 +519,10 @@ export class TabsTitleControl extends TitleControl { return !isCopy || source.id === target.id; } - private getTabActions(identifier: IEditorIdentifier): IAction[] { + protected getContextMenuActions(identifier: IEditorIdentifier): IAction[] { + const actions = super.getContextMenuActions(identifier); const {editor, group} = identifier; - // Enablement - this.closeOtherEditorsAction.enabled = group.count > 1; - this.pinEditorAction.enabled = !group.isPinned(editor); - this.closeRightEditorsAction.enabled = group.indexOf(editor) !== group.count - 1; - - // Actions: For all editors - const actions: IAction[] = [ - this.closeEditorAction, - this.closeOtherEditorsAction, - this.closeRightEditorsAction, - this.closeEditorsInGroupAction - ]; - - if (this.previewEditors) { - actions.push(new Separator(), this.pinEditorAction); - } - // Actions: For active editor if (group.isActive(editor)) { const editorActions = this.getEditorActions(group); diff --git a/src/vs/workbench/browser/parts/editor/titleControl.ts b/src/vs/workbench/browser/parts/editor/titleControl.ts index 2fb588dfd00..afa30ec9cec 100644 --- a/src/vs/workbench/browser/parts/editor/titleControl.ts +++ b/src/vs/workbench/browser/parts/editor/titleControl.ts @@ -13,18 +13,21 @@ import {IAction, Action} from 'vs/base/common/actions'; import errors = require('vs/base/common/errors'); import {Builder} from 'vs/base/browser/builder'; import DOM = require('vs/base/browser/dom'); +import {TPromise} from 'vs/base/common/winjs.base'; import {BaseEditor, IEditorInputActionContext} from 'vs/workbench/browser/parts/editor/baseEditor'; import {RunOnceScheduler} from 'vs/base/common/async'; -import {IEditorStacksModel, IEditorGroup, EditorInput} from 'vs/workbench/common/editor'; +import {IEditorStacksModel, IEditorGroup, IEditorIdentifier, EditorInput, IWorkbenchEditorConfiguration} from 'vs/workbench/common/editor'; import {EventType as BaseEventType} from 'vs/base/common/events'; import {IActionItem, ActionsOrientation, Separator} from 'vs/base/browser/ui/actionbar/actionbar'; import {ToolBar} from 'vs/base/browser/ui/toolbar/toolbar'; import {IWorkbenchEditorService} from 'vs/workbench/services/editor/common/editorService'; import {IContextMenuService} from 'vs/platform/contextview/browser/contextView'; import {Position} from 'vs/platform/editor/common/editor'; +import {IConfigurationService} from 'vs/platform/configuration/common/configuration'; import {IEditorGroupService} from 'vs/workbench/services/group/common/groupService'; import {IMessageService, Severity} from 'vs/platform/message/common/message'; import {QuickOpenAction} from 'vs/workbench/browser/quickopen'; +import {StandardMouseEvent} from 'vs/base/browser/mouseEvent'; import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry'; import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation'; import {IKeybindingService} from 'vs/platform/keybinding/common/keybindingService'; @@ -66,6 +69,9 @@ export abstract class TitleControl { protected splitEditorAction: SplitEditorAction; protected showAllEditorsAction: ShowAllEditorsAction; + private previewEditors: boolean; + private showTabs: boolean; + private mapActionsToEditors: { [editorId: string]: IToolbarActions; }; private scheduler: RunOnceScheduler; private refreshScheduled: boolean; @@ -73,6 +79,7 @@ export abstract class TitleControl { constructor( @IContextMenuService protected contextMenuService: IContextMenuService, @IInstantiationService protected instantiationService: IInstantiationService, + @IConfigurationService protected configurationService: IConfigurationService, @IWorkbenchEditorService protected editorService: IWorkbenchEditorService, @IEditorGroupService protected editorGroupService: IEditorGroupService, @IKeybindingService protected keybindingService: IKeybindingService, @@ -83,10 +90,22 @@ export abstract class TitleControl { this.stacks = editorGroupService.getStacksModel(); this.mapActionsToEditors = Object.create(null); + this.onConfigurationUpdated(configurationService.getConfiguration()); + this.scheduler = new RunOnceScheduler(() => this.onSchedule(), 0); this.toDispose.push(this.scheduler); this.initActions(); + this.registerListeners(); + } + + private registerListeners(): void { + this.toDispose.push(this.configurationService.onDidUpdateConfiguration(e => this.onConfigurationUpdated(e.config))); + } + + private onConfigurationUpdated(config: IWorkbenchEditorConfiguration): void { + this.previewEditors = config.workbench.previewEditors; + this.showTabs = config.workbench.showEditorTabs; } private updateActionEnablement(): void { @@ -335,6 +354,55 @@ export abstract class TitleControl { return { primary, secondary }; } + protected onContextMenu(identifier: IEditorIdentifier, e: Event, node: HTMLElement): void { + let anchor: HTMLElement | { x: number, y: number } = node; + if (e instanceof MouseEvent) { + const event = new StandardMouseEvent(e); + anchor = { x: event.posx, y: event.posy }; + } + + this.contextMenuService.showContextMenu({ + getAnchor: () => anchor, + getActions: () => TPromise.as(this.getContextMenuActions(identifier)), + getActionsContext: () => identifier, + getKeyBinding: (action) => { + var opts = this.keybindingService.lookupKeybindings(action.id); + if (opts.length > 0) { + return opts[0]; // only take the first one + } + + return null; + } + }); + } + + protected getContextMenuActions(identifier: IEditorIdentifier): IAction[] { + const {editor, group} = identifier; + + // Enablement + this.closeOtherEditorsAction.enabled = group.count > 1; + this.pinEditorAction.enabled = !group.isPinned(editor); + this.closeRightEditorsAction.enabled = group.indexOf(editor) !== group.count - 1; + + // Actions: For all editors + const actions: IAction[] = [ + this.closeEditorAction, + this.closeOtherEditorsAction + ]; + + if (this.showTabs) { + actions.push(this.closeRightEditorsAction); + } + + actions.push(this.closeEditorsInGroupAction); + + if (this.previewEditors) { + actions.push(new Separator(), this.pinEditorAction); + } + + return actions; + } + public dispose(): void { dispose(this.toDispose); -- GitLab