diff --git a/src/vs/workbench/browser/parts/editor/noTabsTitleControl.ts b/src/vs/workbench/browser/parts/editor/noTabsTitleControl.ts index e2436ded5c76f..70ada147ef18f 100644 --- a/src/vs/workbench/browser/parts/editor/noTabsTitleControl.ts +++ b/src/vs/workbench/browser/parts/editor/noTabsTitleControl.ts @@ -6,13 +6,9 @@ 'use strict'; import 'vs/css!./media/notabstitle'; -import {IAction} from 'vs/base/common/actions'; -import {prepareActions} from 'vs/workbench/browser/actionBarRegistry'; import errors = require('vs/base/common/errors'); -import arrays = require('vs/base/common/arrays'); -import {IEditorGroup, EditorInput} from 'vs/workbench/common/editor'; +import {IEditorGroup} from 'vs/workbench/common/editor'; import DOM = require('vs/base/browser/dom'); -import {ToolBar} from 'vs/base/browser/ui/toolbar/toolbar'; import {TitleControl} from 'vs/workbench/browser/parts/editor/titleControl'; export class NoTabsTitleControl extends TitleControl { @@ -21,11 +17,6 @@ export class NoTabsTitleControl extends TitleControl { private titleDecoration: HTMLElement; private titleDescription: HTMLElement; - private editorActionsToolbar: ToolBar; - - private currentPrimaryEditorActionIds: string[] = []; - private currentSecondaryEditorActionIds: string[] = []; - public setContext(group: IEditorGroup): void { super.setContext(group); @@ -67,11 +58,11 @@ export class NoTabsTitleControl extends TitleControl { // Right Actions Container const actionsContainer = document.createElement('div'); DOM.addClass(actionsContainer, 'title-actions'); - - this.editorActionsToolbar = this.doCreateToolbar(actionsContainer); - this.titleContainer.appendChild(actionsContainer); + // Editor actions toolbar + this.createEditorActionsToolBar(actionsContainer); + // Context Menu this.toDispose.push(DOM.addDisposableListener(this.titleContainer, DOM.EventType.CONTEXT_MENU, (e: Event) => this.onContextMenu({ group: this.context, editor: this.context.activeEditor }, e, this.titleContainer))); } @@ -121,10 +112,7 @@ export class NoTabsTitleControl extends TitleControl { this.titleLabel.innerText = ''; this.titleDescription.innerText = ''; - this.editorActionsToolbar.setActions([], [])(); - - this.currentPrimaryEditorActionIds = []; - this.currentSecondaryEditorActionIds = []; + this.clearEditorActionsToolbar(); return; // return early if we are being closed } @@ -168,34 +156,6 @@ export class NoTabsTitleControl extends TitleControl { } // Update Editor Actions Toolbar - let primaryEditorActions: IAction[] = []; - let secondaryEditorActions: IAction[] = []; - if (isActive) { - const editorActions = this.getEditorActions({ group, editor }); - primaryEditorActions = prepareActions(editorActions.primary); - if (isActive && editor instanceof EditorInput && editor.supportsSplitEditor()) { - primaryEditorActions.push(this.splitEditorAction); - } - secondaryEditorActions = prepareActions(editorActions.secondary); - } - - const primaryEditorActionIds = primaryEditorActions.map(a => a.id); - primaryEditorActionIds.push(this.closeEditorAction.id); - const secondaryEditorActionIds = secondaryEditorActions.map(a => a.id); - - if (!arrays.equals(primaryEditorActionIds, this.currentPrimaryEditorActionIds) || !arrays.equals(secondaryEditorActionIds, this.currentSecondaryEditorActionIds)) { - this.editorActionsToolbar.setActions(primaryEditorActions, secondaryEditorActions)(); - this.editorActionsToolbar.addPrimaryAction(this.closeEditorAction)(); - - this.currentPrimaryEditorActionIds = primaryEditorActionIds; - this.currentSecondaryEditorActionIds = secondaryEditorActionIds; - } - } - - public dispose(): void { - super.dispose(); - - // Toolbars - this.editorActionsToolbar.dispose(); + this.updateEditorActionsToolbar(); } } \ No newline at end of file diff --git a/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts b/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts index d076e6c8cf7fb..815c0975e53bf 100644 --- a/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts +++ b/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts @@ -7,19 +7,15 @@ import 'vs/css!./media/tabstitle'; import nls = require('vs/nls'); -import {IAction} from 'vs/base/common/actions'; -import {prepareActions} from 'vs/workbench/browser/actionBarRegistry'; -import arrays = require('vs/base/common/arrays'); import errors = require('vs/base/common/errors'); import DOM = require('vs/base/browser/dom'); import {isMacintosh} from 'vs/base/common/platform'; import {MIME_BINARY} from 'vs/base/common/mime'; import {Position} from 'vs/platform/editor/common/editor'; import {IEditorGroup, IEditorIdentifier, asFileEditorInput} 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, KeyCode} from 'vs/base/common/keyCodes'; -import {ActionBar, Separator} from 'vs/base/browser/ui/actionbar/actionbar'; +import {ActionBar} from 'vs/base/browser/ui/actionbar/actionbar'; 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'; @@ -42,13 +38,8 @@ export class TabsTitleControl extends TitleControl { private tabsContainer: HTMLElement; private activeTab: HTMLElement; private scrollbar: ScrollableElement; - - private editorActionsToolbar: ToolBar; private tabDisposeables: IDisposable[] = []; - private currentPrimaryGroupActionIds: string[] = []; - private currentSecondaryGroupActionIds: string[] = []; - constructor( @IContextMenuService contextMenuService: IContextMenuService, @IInstantiationService instantiationService: IInstantiationService, @@ -64,9 +55,6 @@ export class TabsTitleControl extends TitleControl { ) { super(contextMenuService, instantiationService, configurationService, editorService, editorGroupService, keybindingService, telemetryService, messageService, menuService, quickOpenService); - this.currentPrimaryGroupActionIds = []; - this.currentSecondaryGroupActionIds = []; - this.tabDisposeables = []; } @@ -160,11 +148,13 @@ export class TabsTitleControl extends TitleControl { } })); - // Editor Actions + // Editor Actions Container const editorActionsContainer = document.createElement('div'); DOM.addClass(editorActionsContainer, 'editor-actions'); this.titleContainer.appendChild(editorActionsContainer); - this.editorActionsToolbar = this.doCreateToolbar(editorActionsContainer); + + // Editor Actions Toolbar + this.createEditorActionsToolBar(editorActionsContainer); } public allowDragging(element: HTMLElement): boolean { @@ -221,17 +211,7 @@ export class TabsTitleControl extends TitleControl { }); // Update Editor Actions Toolbar - const groupActions = this.getGroupActions(group); - const primaryGroupActions = groupActions.primary; - const secondaryGroupActions = groupActions.secondary; - const primaryGroupActionIds = primaryGroupActions.map(a => a.id); - const secondaryGroupActionIds = secondaryGroupActions.map(a => a.id); - - if (!arrays.equals(primaryGroupActionIds, this.currentPrimaryGroupActionIds) || !arrays.equals(secondaryGroupActionIds, this.currentSecondaryGroupActionIds)) { - this.editorActionsToolbar.setActions(primaryGroupActions, secondaryGroupActions)(); - this.currentPrimaryGroupActionIds = primaryGroupActionIds; - this.currentSecondaryGroupActionIds = secondaryGroupActionIds; - } + this.updateEditorActionsToolbar(); // Ensure the active tab is always revealed this.layout(); @@ -243,10 +223,7 @@ export class TabsTitleControl extends TitleControl { if (!editor) { this.clearTabs(); - this.editorActionsToolbar.setActions([], [])(); - - this.currentPrimaryGroupActionIds = []; - this.currentSecondaryGroupActionIds = []; + this.clearEditorActionsToolbar(); return; // return early if we are being closed } @@ -346,10 +323,6 @@ export class TabsTitleControl extends TitleControl { scrollLeft: this.activeTab.offsetLeft }); } - - // Update enablement of certain actions that depend on overflow - const isOverflowing = (totalContainerWidth > visibleContainerWidth); - this.showEditorsInGroupAction.enabled = isOverflowing; } private hookTabListeners(tab: HTMLElement, identifier: IEditorIdentifier): void { @@ -531,30 +504,4 @@ export class TabsTitleControl extends TitleControl { return !isCopy || source.id === target.id; } - - protected getContextMenuActions(identifier: IEditorIdentifier): IAction[] { - const actions = super.getContextMenuActions(identifier); - const {editor, group} = identifier; - - // Actions: For active editor - if (group.isActive(editor)) { - const editorActions = this.getEditorActions(identifier); - if (editorActions.primary.length) { - actions.push(new Separator(), ...prepareActions(editorActions.primary)); - } - - if (editorActions.secondary.length) { - actions.push(new Separator(), ...prepareActions(editorActions.secondary)); - } - } - - return actions; - } - - public dispose(): void { - super.dispose(); - - // Toolbar - this.editorActionsToolbar.dispose(); - } } \ No newline at end of file diff --git a/src/vs/workbench/browser/parts/editor/titleControl.ts b/src/vs/workbench/browser/parts/editor/titleControl.ts index 8027d06e800e3..0da21c5077831 100644 --- a/src/vs/workbench/browser/parts/editor/titleControl.ts +++ b/src/vs/workbench/browser/parts/editor/titleControl.ts @@ -8,20 +8,20 @@ import 'vs/css!./media/titlecontrol'; import nls = require('vs/nls'); import {Registry} from 'vs/platform/platform'; -import {Scope, IActionBarRegistry, Extensions} from 'vs/workbench/browser/actionBarRegistry'; +import {Scope, IActionBarRegistry, Extensions, prepareActions} from 'vs/workbench/browser/actionBarRegistry'; import {IAction, Action} from 'vs/base/common/actions'; import errors = require('vs/base/common/errors'); 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 arrays = require('vs/base/common/arrays'); import {IEditorStacksModel, IEditorGroup, IEditorIdentifier, EditorInput, IWorkbenchEditorConfiguration, IStacksModelChangeEvent, getResource} 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'; @@ -30,7 +30,7 @@ import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry'; import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation'; import {IQuickOpenService} from 'vs/workbench/services/quickopen/common/quickOpenService'; import {IKeybindingService} from 'vs/platform/keybinding/common/keybinding'; -import {CloseEditorsInGroupAction, MoveGroupLeftAction, MoveGroupRightAction, SplitEditorAction, CloseEditorAction, KeepEditorAction, CloseOtherEditorsInGroupAction, CloseRightEditorsInGroupAction, ShowEditorsInGroupAction} from 'vs/workbench/browser/parts/editor/editorActions'; +import {CloseEditorsInGroupAction, SplitEditorAction, CloseEditorAction, KeepEditorAction, CloseOtherEditorsInGroupAction, CloseRightEditorsInGroupAction, ShowEditorsInGroupAction} from 'vs/workbench/browser/parts/editor/editorActions'; import {IDisposable, dispose} from 'vs/base/common/lifecycle'; import {createActionItem, fillInActions} from 'vs/platform/actions/browser/menuItemActionItem'; import {IMenuService, IMenu, MenuId} from 'vs/platform/actions/common/actions'; @@ -67,8 +67,6 @@ export abstract class TitleControl implements ITitleAreaControl { protected pinEditorAction: KeepEditorAction; protected closeOtherEditorsAction: CloseOtherEditorsInGroupAction; protected closeRightEditorsAction: CloseRightEditorsInGroupAction; - protected moveGroupLeftAction: MoveGroupLeftAction; - protected moveGroupRightAction: MoveGroupRightAction; protected closeEditorsInGroupAction: CloseEditorsInGroupAction; protected splitEditorAction: SplitEditorAction; protected showEditorsInGroupAction: ShowEditorsInGroupAction; @@ -78,6 +76,10 @@ export abstract class TitleControl implements ITitleAreaControl { private previewEditors: boolean; private showTabs: boolean; + private currentPrimaryEditorActionIds: string[] = []; + private currentSecondaryEditorActionIds: string[] = []; + protected editorActionsToolbar: ToolBar; + private mapActionsToEditors: { [editorId: string]: IToolbarActions; }; private scheduler: RunOnceScheduler; private refreshScheduled: boolean; @@ -222,16 +224,12 @@ export abstract class TitleControl implements ITitleAreaControl { this.closeRightEditorsAction = this.instantiationService.createInstance(CloseRightEditorsInGroupAction, CloseRightEditorsInGroupAction.ID, nls.localize('closeRight', "Close to the Right")); this.closeEditorsInGroupAction = this.instantiationService.createInstance(CloseEditorsInGroupAction, CloseEditorsInGroupAction.ID, nls.localize('closeAll', "Close All")); this.pinEditorAction = this.instantiationService.createInstance(KeepEditorAction, KeepEditorAction.ID, nls.localize('keepOpen', "Keep Open")); - this.showEditorsInGroupAction = this.instantiationService.createInstance(ShowEditorsInGroupAction, ShowEditorsInGroupAction.ID, ShowEditorsInGroupAction.LABEL); + this.showEditorsInGroupAction = this.instantiationService.createInstance(ShowEditorsInGroupAction, ShowEditorsInGroupAction.ID, nls.localize('showOpenedEditors', "Show Opened Editors")); this.splitEditorAction = this.instantiationService.createInstance(SplitEditorAction, SplitEditorAction.ID, SplitEditorAction.LABEL); - this.moveGroupLeftAction = this.instantiationService.createInstance(MoveGroupLeftAction, MoveGroupLeftAction.ID, nls.localize('moveLeft', "Move Left")); - this.moveGroupRightAction = this.instantiationService.createInstance(MoveGroupRightAction, MoveGroupRightAction.ID, nls.localize('moveRight', "Move Right")); - - this.showEditorsInGroupAction.class = 'show-group-editors-action'; } - protected doCreateToolbar(container: HTMLElement): ToolBar { - const toolbar = new ToolBar(container, this.contextMenuService, { + protected createEditorActionsToolBar(container: HTMLElement): void { + this.editorActionsToolbar = new ToolBar(container, this.contextMenuService, { actionItemProvider: (action: Action) => this.actionItemProvider(action), orientation: ActionsOrientation.HORIZONTAL, ariaLabel: nls.localize('araLabelEditorActions', "Editor actions"), @@ -246,7 +244,7 @@ export abstract class TitleControl implements ITitleAreaControl { }); // Action Run Handling - this.toDispose.push(toolbar.actionRunner.addListener2(BaseEventType.RUN, (e: any) => { + this.toDispose.push(this.editorActionsToolbar.actionRunner.addListener2(BaseEventType.RUN, (e: any) => { // Check for Error if (e.error && !errors.isPromiseCanceledError(e.error)) { @@ -258,8 +256,6 @@ export abstract class TitleControl implements ITitleAreaControl { this.telemetryService.publicLog('workbenchActionExecuted', { id: e.action.id, from: 'editorPart' }); } })); - - return toolbar; } protected actionItemProvider(action: Action): IActionItem { @@ -350,43 +346,58 @@ export abstract class TitleControl implements ITitleAreaControl { }; } - protected getGroupActions(group: IEditorGroup): IToolbarActions { - const editor = group.activeEditor; - const primary: IAction[] = []; + protected updateEditorActionsToolbar(): void { + const group = this.context; + if (!group) { + return; + } - // Overflow - primary.push(this.showEditorsInGroupAction); + const editor = group && group.activeEditor; + const isActive = this.stacks.isActive(group); + + // Update Editor Actions Toolbar + let primaryEditorActions: IAction[] = []; + let secondaryEditorActions: IAction[] = []; + if (isActive) { + const editorActions = this.getEditorActions({ group, editor }); + primaryEditorActions = prepareActions(editorActions.primary); + if (isActive && editor instanceof EditorInput && editor.supportsSplitEditor()) { + primaryEditorActions.push(this.splitEditorAction); + } + secondaryEditorActions = prepareActions(editorActions.secondary); + } - // Splitting - if (editor instanceof EditorInput && editor.supportsSplitEditor()) { - primary.push(this.splitEditorAction); + if (this.showTabs) { + secondaryEditorActions.push(new Separator()); + secondaryEditorActions.push(this.showEditorsInGroupAction); + secondaryEditorActions.push(new Separator()); + secondaryEditorActions.push(this.closeEditorsInGroupAction); } - // Enablement - switch (this.stacks.positionOfGroup(group)) { - case Position.LEFT: - this.moveGroupLeftAction.enabled = false; - this.moveGroupRightAction.enabled = this.stacks.groups.length > 1; - break; - - case Position.CENTER: - this.moveGroupRightAction.enabled = this.stacks.groups.length > 2; - break; - - case Position.RIGHT: - this.moveGroupRightAction.enabled = false; - break; + const primaryEditorActionIds = primaryEditorActions.map(a => a.id); + if (!this.showTabs) { + primaryEditorActionIds.push(this.closeEditorAction.id); // always show "Close" when tabs are disabled } - // Return actions - const secondary = [ - this.moveGroupLeftAction, - this.moveGroupRightAction, - new Separator(), - this.closeEditorsInGroupAction - ]; + const secondaryEditorActionIds = secondaryEditorActions.map(a => a.id); - return { primary, secondary }; + if (!arrays.equals(primaryEditorActionIds, this.currentPrimaryEditorActionIds) || !arrays.equals(secondaryEditorActionIds, this.currentSecondaryEditorActionIds)) { + this.editorActionsToolbar.setActions(primaryEditorActions, secondaryEditorActions)(); + + if (!this.showTabs) { + this.editorActionsToolbar.addPrimaryAction(this.closeEditorAction)(); + } + + this.currentPrimaryEditorActionIds = primaryEditorActionIds; + this.currentSecondaryEditorActionIds = secondaryEditorActionIds; + } + } + + protected clearEditorActionsToolbar(): void { + this.editorActionsToolbar.setActions([], [])(); + + this.currentPrimaryEditorActionIds = []; + this.currentSecondaryEditorActionIds = []; } protected onContextMenu(identifier: IEditorIdentifier, e: Event, node: HTMLElement): void { @@ -449,11 +460,12 @@ export abstract class TitleControl implements ITitleAreaControl { this.closeRightEditorsAction, this.closeOtherEditorsAction, this.closeEditorsInGroupAction, - this.moveGroupLeftAction, - this.moveGroupRightAction, this.pinEditorAction ].forEach((action) => { action.dispose(); }); + + // Toolbar + this.editorActionsToolbar.dispose(); } } \ No newline at end of file