提交 4dcdbc27 编写于 作者: B Benjamin Pasero 提交者: GitHub

Merge pull request #7534 from Microsoft/ben/7182

explore #7182
......@@ -779,6 +779,7 @@ export const EventType = {
MOUSE_MOVE: 'mousemove',
MOUSE_OUT: 'mouseout',
CONTEXT_MENU: 'contextmenu',
WHEEL: 'wheel',
// Keyboard
KEY_DOWN: 'keydown',
KEY_PRESS: 'keypress',
......
......@@ -244,6 +244,11 @@ export class ScrollableElement extends Widget {
deltaX = e.deltaY;
}
if (this._options.scrollYToX && !deltaX) {
deltaX = e.deltaY;
deltaY = 0;
}
if (Platform.isMacintosh) {
// Give preference to vertical scrolling
if (deltaY && Math.abs(deltaX) < 0.2) {
......@@ -412,6 +417,7 @@ function resolveOptions(opts: ScrollableElementCreationOptions): ScrollableEleme
useShadows: (typeof opts.useShadows !== 'undefined' ? opts.useShadows : true),
handleMouseWheel: (typeof opts.handleMouseWheel !== 'undefined' ? opts.handleMouseWheel : true),
flipAxes: (typeof opts.flipAxes !== 'undefined' ? opts.flipAxes : false),
scrollYToX: (typeof opts.scrollYToX !== 'undefined' ? opts.scrollYToX : false),
mouseWheelScrollSensitivity: (typeof opts.mouseWheelScrollSensitivity !== 'undefined' ? opts.mouseWheelScrollSensitivity : 1),
arrowSize: (typeof opts.arrowSize !== 'undefined' ? opts.arrowSize : 11),
......
......@@ -36,9 +36,14 @@ export interface ScrollableElementCreationOptions {
handleMouseWheel?: boolean;
/**
* Flip axes. Treat vertical scrolling like horizontal and vice-versa.
* Defaults to false;
* Defaults to false.
*/
flipAxes?: boolean;
/**
* If enabled, will scroll horizontally when scrolling vertical.
* Defaults to false.
*/
scrollYToX?: boolean;
/**
* A multiplier to be used on the `deltaX` and `deltaY` of mouse wheel scroll events.
* Defaults to 1.
......@@ -115,6 +120,7 @@ export interface ScrollableElementResolvedOptions {
useShadows: boolean;
handleMouseWheel: boolean;
flipAxes: boolean;
scrollYToX: boolean;
mouseWheelScrollSensitivity: number;
arrowSize: number;
listenOnDomNode: HTMLElement;
......
......@@ -86,6 +86,9 @@ export class ToolBar {
public set context(context: any) {
this.actionBar.context = context;
if (this.toggleMenuActionItem) {
this.toggleMenuActionItem.setActionContext(context);
}
}
public getContainer(): Builder {
......@@ -228,6 +231,14 @@ export class DropdownMenuActionItem extends BaseActionItem {
this.toUnbind = this.addEmitter2(this.dropdownMenu);
}
public setActionContext(newContext: any): void {
super.setActionContext(newContext);
if (this.dropdownMenu) {
this.dropdownMenu.menuOptions.context = newContext;
}
}
public show(): void {
if (this.dropdownMenu) {
this.dropdownMenu.show();
......
......@@ -26,6 +26,7 @@ import {BinaryResourceDiffEditor} from 'vs/workbench/browser/parts/editor/binary
import {IEditorGroupService} from 'vs/workbench/services/group/common/groupService';
import {IFrameEditor} from 'vs/workbench/browser/parts/editor/iframeEditor';
import {IFrameEditorInput} from 'vs/workbench/common/editor/iframeEditorInput';
import {IConfigurationRegistry, Extensions as ConfigurationExtensions} from 'vs/platform/configuration/common/configurationRegistry';
import {ChangeEncodingAction, ChangeEOLAction, ChangeModeAction, EditorStatus} from 'vs/workbench/browser/parts/editor/editorStatus';
import {IWorkbenchActionRegistry, Extensions as ActionExtensions} from 'vs/workbench/common/actionRegistry';
import {Scope, IActionBarRegistry, Extensions as ActionBarExtensions, ActionBarContributor} from 'vs/workbench/browser/actionBarRegistry';
......@@ -33,7 +34,7 @@ import {SyncActionDescriptor} from 'vs/platform/actions/common/actions';
import {SyncDescriptor} from 'vs/platform/instantiation/common/descriptors';
import {KeyMod, KeyCode} from 'vs/base/common/keyCodes';
import {EditorStacksModel} from 'vs/workbench/common/editor/editorStacksModel';
import {CloseEditorsInGroupAction, CloseEditorsInOtherGroupsAction, CloseAllEditorsAction, MoveGroupLeftAction, MoveGroupRightAction, SplitEditorAction, PinEditorAction, UnpinEditorAction, CloseOtherEditorsInGroupAction, OpenToSideAction,
import {CloseEditorsInGroupAction, CloseEditorsInOtherGroupsAction, CloseAllEditorsAction, MoveGroupLeftAction, MoveGroupRightAction, SplitEditorAction, PinEditorAction, CloseOtherEditorsInGroupAction, OpenToSideAction,
NavigateBetweenGroupsAction, FocusFirstGroupAction, FocusSecondGroupAction, FocusThirdGroupAction, EvenGroupWidthsAction, MaximizeGroupAction, MinimizeOtherGroupsAction, FocusPreviousGroup, FocusNextGroup, ShowEditorsInLeftGroupAction,
toEditorQuickOpenEntry, CloseLeftEditorsInGroupAction, CloseRightEditorsInGroupAction, OpenNextEditor, OpenPreviousEditor, NavigateBackwardsAction, NavigateForwardAction, ReopenClosedEditorAction, OpenPreviousEditorInGroupAction, NAVIGATE_IN_LEFT_GROUP_PREFIX,
GlobalQuickOpenAction, OpenPreviousEditorFromHistoryAction, QuickOpenNavigateNextAction, QuickOpenNavigatePreviousAction, ShowAllEditorsAction, NAVIGATE_ALL_EDITORS_GROUP_PREFIX, ClearEditorHistoryAction, ShowEditorsInCenterGroupAction,
......@@ -356,7 +357,6 @@ registry.registerWorkbenchAction(new SyncActionDescriptor(OpenPreviousEditor, Op
}), 'View: Open Previous Editor', category);
registry.registerWorkbenchAction(new SyncActionDescriptor(ReopenClosedEditorAction, ReopenClosedEditorAction.ID, ReopenClosedEditorAction.LABEL, { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_T }), 'View: Reopen Closed Editor', category);
registry.registerWorkbenchAction(new SyncActionDescriptor(PinEditorAction, PinEditorAction.ID, PinEditorAction.LABEL, { primary: KeyMod.chord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.Enter) }), 'View: Pin Editor', category);
registry.registerWorkbenchAction(new SyncActionDescriptor(UnpinEditorAction, UnpinEditorAction.ID, UnpinEditorAction.LABEL), 'View: Unpin Editor', category);
registry.registerWorkbenchAction(new SyncActionDescriptor(CloseAllEditorsAction, CloseAllEditorsAction.ID, CloseAllEditorsAction.LABEL, { primary: KeyMod.chord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_W) }), 'View: Close All Editors', category);
registry.registerWorkbenchAction(new SyncActionDescriptor(CloseLeftEditorsInGroupAction, CloseLeftEditorsInGroupAction.ID, CloseLeftEditorsInGroupAction.LABEL), 'View: Close Editors to the Left', category);
registry.registerWorkbenchAction(new SyncActionDescriptor(CloseRightEditorsInGroupAction, CloseRightEditorsInGroupAction.ID, CloseRightEditorsInGroupAction.LABEL), 'View: Close Editors to the Right', category);
......@@ -394,4 +394,20 @@ registry.registerWorkbenchAction(new SyncActionDescriptor(OpenPreviousEditorFrom
registry.registerWorkbenchAction(new SyncActionDescriptor(ClearEditorHistoryAction, ClearEditorHistoryAction.ID, ClearEditorHistoryAction.LABEL), 'Clear Editor History');
registry.registerWorkbenchAction(new SyncActionDescriptor(RemoveFromEditorHistoryAction, RemoveFromEditorHistoryAction.ID, RemoveFromEditorHistoryAction.LABEL), 'Remove From Editor History');
registry.registerWorkbenchAction(new SyncActionDescriptor(QuickOpenNavigateNextAction, QuickOpenNavigateNextAction.ID, QuickOpenNavigateNextAction.LABEL, navigateKeybinding(false), KbExpr.has('inQuickOpen')), 'Navigate Next in Quick Open');
registry.registerWorkbenchAction(new SyncActionDescriptor(QuickOpenNavigatePreviousAction, QuickOpenNavigatePreviousAction.ID, QuickOpenNavigatePreviousAction.LABEL, navigateKeybinding(true), KbExpr.has('inQuickOpen'), KeybindingsRegistry.WEIGHT.workbenchContrib(50)), 'Navigate Previous in Quick Open');
\ No newline at end of file
registry.registerWorkbenchAction(new SyncActionDescriptor(QuickOpenNavigatePreviousAction, QuickOpenNavigatePreviousAction.ID, QuickOpenNavigatePreviousAction.LABEL, navigateKeybinding(true), KbExpr.has('inQuickOpen'), KeybindingsRegistry.WEIGHT.workbenchContrib(50)), 'Navigate Previous in Quick Open');
// Configuration
let configurationRegistry = <IConfigurationRegistry>Registry.as(ConfigurationExtensions.Configuration);
configurationRegistry.registerConfiguration({
'id': 'workbench',
'order': 7,
'title': nls.localize('workbenchConfigurationTitle', "Workbench configuration"),
'type': 'object',
'properties': {
'workbench.showTabs': {
'type': 'boolean',
'description': nls.localize('showTabs', "Controls if opened editors should show in tabs or not."),
'default': false
}
}
});
\ No newline at end of file
......@@ -7,13 +7,13 @@
import {TPromise} from 'vs/base/common/winjs.base';
import nls = require('vs/nls');
import {Action} from 'vs/base/common/actions';
import {EditorInput, getUntitledOrFileResource, TextEditorOptions, EditorOptions, IEditorIdentifier} from 'vs/workbench/common/editor';
import {EditorInput, getUntitledOrFileResource, TextEditorOptions, EditorOptions, IEditorIdentifier, IEditorContext} from 'vs/workbench/common/editor';
import {QuickOpenEntryGroup} from 'vs/base/parts/quickopen/browser/quickOpenModel';
import {EditorQuickOpenEntry, EditorQuickOpenEntryGroup, IEditorQuickOpenEntry, QuickOpenAction} from 'vs/workbench/browser/quickopen';
import {IWorkbenchEditorService, GroupArrangement} from 'vs/workbench/services/editor/common/editorService';
import {IQuickOpenService, IPickOpenEntry} from 'vs/workbench/services/quickopen/common/quickOpenService';
import {IPartService} from 'vs/workbench/services/part/common/partService';
import {Position, IEditor, Direction, IResourceInput} from 'vs/platform/editor/common/editor';
import {Position, IEditor, Direction, IResourceInput, IEditorInput} from 'vs/platform/editor/common/editor';
import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation';
import {IHistoryService} from 'vs/workbench/services/history/common/history';
import {IKeybindingService} from 'vs/platform/keybinding/common/keybindingService';
......@@ -34,7 +34,7 @@ export class SplitEditorAction extends Action {
super(id, label, 'split-editor-action');
}
public run(context: IEditorContext): TPromise<any> {
public run(context?: IEditorContext): TPromise<any> {
let editorToSplit: IEditor;
if (context) {
editorToSplit = this.editorService.getVisibleEditors()[this.editorGroupService.getStacksModel().positionOfGroup(context.group)];
......@@ -437,7 +437,7 @@ export class CloseEditorAction extends Action {
super(id, label, 'close-editor-action');
}
public run(context: IEditorContext): TPromise<any> {
public run(context?: IEditorContext): TPromise<any> {
let position = context ? this.editorGroupService.getStacksModel().positionOfGroup(context.group) : null;
// Close Active Editor
......@@ -466,50 +466,24 @@ export class CloseEditorAction extends Action {
}
}
export class CloseEditorsInGroupAction extends Action {
export class CloseLeftEditorsInGroupAction extends Action {
public static ID = 'workbench.action.closeEditorsInGroup';
public static LABEL = nls.localize('closeEditorsInGroup', "Close All Editors in Group");
public static ID = 'workbench.action.closeEditorsToTheLeft';
public static LABEL = nls.localize('closeEditorsToTheLeft', "Close Editors to the Left");
constructor(
id: string,
label: string,
@IEditorGroupService private editorGroupService: IEditorGroupService,
@IWorkbenchEditorService private editorService: IWorkbenchEditorService
@IWorkbenchEditorService private editorService: IWorkbenchEditorService,
@IEditorGroupService private groupService: IEditorGroupService
) {
super(id, label);
}
public run(context: IEditorContext): TPromise<any> {
let position = context ? this.editorGroupService.getStacksModel().positionOfGroup(context.group) : null;
if (typeof position !== 'number') {
let activeEditor = this.editorService.getActiveEditor();
if (activeEditor) {
position = activeEditor.position;
}
}
if (typeof position === 'number') {
return this.editorService.closeEditors(position);
}
return TPromise.as(false);
}
}
export class CloseLeftEditorsInGroupAction extends Action {
public static ID = 'workbench.action.closeEditorsToTheLeft';
public static LABEL = nls.localize('closeEditorsToTheLeft', "Close Editors to the Left");
constructor(id: string, label: string, @IWorkbenchEditorService private editorService: IWorkbenchEditorService) {
super(id, label);
}
public run(): TPromise<any> {
let activeEditor = this.editorService.getActiveEditor();
if (activeEditor) {
return this.editorService.closeEditors(activeEditor.position, activeEditor.input, Direction.LEFT);
public run(context?: IEditorContext): TPromise<any> {
let editor = getTarget(this.editorService, this.groupService, context);
if (editor) {
return this.editorService.closeEditors(editor.position, editor.input, Direction.LEFT);
}
return TPromise.as(false);
......@@ -521,14 +495,19 @@ export class CloseRightEditorsInGroupAction extends Action {
public static ID = 'workbench.action.closeEditorsToTheRight';
public static LABEL = nls.localize('closeEditorsToTheRight', "Close Editors to the Right");
constructor(id: string, label: string, @IWorkbenchEditorService private editorService: IWorkbenchEditorService) {
constructor(
id: string,
label: string,
@IWorkbenchEditorService private editorService: IWorkbenchEditorService,
@IEditorGroupService private groupService: IEditorGroupService
) {
super(id, label);
}
public run(): TPromise<any> {
let activeEditor = this.editorService.getActiveEditor();
if (activeEditor) {
return this.editorService.closeEditors(activeEditor.position, activeEditor.input, Direction.RIGHT);
public run(context?: IEditorContext): TPromise<any> {
let editor = getTarget(this.editorService, this.groupService, context);
if (editor) {
return this.editorService.closeEditors(editor.position, editor.input, Direction.RIGHT);
}
return TPromise.as(false);
......@@ -563,7 +542,7 @@ export class CloseEditorsInOtherGroupsAction extends Action {
super(id, label);
}
public run(context: IEditorContext): TPromise<any> {
public run(context?: IEditorContext): TPromise<any> {
let position = context ? this.editorGroupService.getStacksModel().positionOfGroup(context.group) : null;
if (typeof position !== 'number') {
let activeEditor = this.editorService.getActiveEditor();
......@@ -594,7 +573,7 @@ export class CloseOtherEditorsInGroupAction extends Action {
super(id, label);
}
public run(context: IEditorContext): TPromise<any> {
public run(context?: IEditorContext): TPromise<any> {
let position = context ? this.editorGroupService.getStacksModel().positionOfGroup(context.group) : null;
let input = context ? context.editor : null;
......@@ -613,10 +592,10 @@ export class CloseOtherEditorsInGroupAction extends Action {
}
}
export class CloseAllEditorsInGroupAction extends Action {
export class CloseEditorsInGroupAction extends Action {
public static ID = 'workbench.files.action.closeAllEditorsInGroup';
public static LABEL = nls.localize('closeAllEditorsInGroup', "Close All Editors in Group");
public static ID = 'workbench.action.closeEditorsInGroup';
public static LABEL = nls.localize('closeEditorsInGroup', "Close All Editors in Group");
constructor(
id: string,
......@@ -624,10 +603,10 @@ export class CloseAllEditorsInGroupAction extends Action {
@IEditorGroupService private editorGroupService: IEditorGroupService,
@IWorkbenchEditorService private editorService: IWorkbenchEditorService
) {
super(id, label, 'action-close-all-files');
super(id, label);
}
public run(context: IEditorContext): TPromise<any> {
public run(context?: IEditorContext): TPromise<any> {
let position = context ? this.editorGroupService.getStacksModel().positionOfGroup(context.group) : null;
if (typeof position !== 'number') {
let activeEditor = this.editorService.getActiveEditor();
......@@ -639,6 +618,8 @@ export class CloseAllEditorsInGroupAction extends Action {
if (typeof position === 'number') {
return this.editorService.closeEditors(position);
}
return TPromise.as(false);
}
}
......@@ -656,7 +637,7 @@ export class MoveGroupLeftAction extends Action {
super(id, label);
}
public run(context: IEditorContext): TPromise<any> {
public run(context?: IEditorContext): TPromise<any> {
let position = context ? this.editorGroupService.getStacksModel().positionOfGroup(context.group) : null;
if (typeof position !== 'number') {
let activeEditor = this.editorService.getActiveEditor();
......@@ -690,7 +671,7 @@ export class MoveGroupRightAction extends Action {
super(id, label);
}
public run(context: IEditorContext): TPromise<any> {
public run(context?: IEditorContext): TPromise<any> {
let position = context ? this.editorGroupService.getStacksModel().positionOfGroup(context.group) : null;
if (typeof position !== 'number') {
let activeEditor = this.editorService.getActiveEditor();
......@@ -783,38 +764,27 @@ export class PinEditorAction extends Action {
super(id, label);
}
public run(): TPromise<any> {
let editor = this.editorService.getActiveEditor();
if (editor) {
this.editorGroupService.pinEditor(editor.position, editor.input);
public run(context?: IEditorContext): TPromise<any> {
let target = getTarget(this.editorService, this.editorGroupService, context);
if (target) {
this.editorGroupService.pinEditor(target.position, target.input);
}
return TPromise.as(true);
}
}
export class UnpinEditorAction extends Action {
public static ID = 'workbench.action.unpinEditor';
public static LABEL = nls.localize('unpinEditor', "Unpin Editor");
constructor(
id: string,
label: string,
@IEditorGroupService private editorGroupService: IEditorGroupService,
@IWorkbenchEditorService private editorService: IWorkbenchEditorService
) {
super(id, label);
function getTarget(editorService: IWorkbenchEditorService, editorGroupService: IEditorGroupService, context?: IEditorContext): { input: IEditorInput, position: Position } {
if (context) {
return { input: context.editor, position: editorGroupService.getStacksModel().positionOfGroup(context.group) };
}
public run(): TPromise<any> {
let editor = this.editorService.getActiveEditor();
if (editor) {
this.editorGroupService.unpinEditor(editor.position, editor.input);
}
return TPromise.as(true);
const activeEditor = editorService.getActiveEditor();
if (activeEditor) {
return { input: activeEditor.input, position: activeEditor.position };
}
return null;
}
export abstract class BaseNavigateEditorAction extends Action {
......@@ -1211,8 +1181,4 @@ export class QuickOpenNavigatePreviousAction extends BaseQuickOpenNavigateAction
interface IEditorPickOpenEntry extends IPickOpenEntry {
identifier: IEditorIdentifier;
}
export interface IEditorContext extends IEditorIdentifier {
event: any;
}
}
\ No newline at end of file
......@@ -453,7 +453,12 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService
});
}
private doCloseEditor(group: EditorGroup, input: EditorInput, focusNext = true): void {
private doCloseEditor(group: EditorGroup, input: EditorInput, focusNext?: boolean): void {
// Only focus next if the group is the active one
if (!(typeof focusNext === 'boolean')) {
focusNext = this.stacks.isActive(group);
}
// Closing the active editor of the group is a bit more work
if (group.activeEditor && group.activeEditor.matches(input)) {
......@@ -1149,8 +1154,7 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService
const visibleEditors: EditorIdentifier[] = [];
const hiddenEditors: EditorIdentifier[] = [];
this.pendingEditorInputsToClose.forEach(identifier => {
const group = identifier.group;
const editor = identifier.editor;
const {group, editor} = identifier;
if (group.isActive(editor)) {
visibleEditors.push(identifier);
......
......@@ -3,13 +3,6 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
/* Title Container */
.monaco-workbench > .part.editor > .content > .one-editor-container > .title {
padding-left: 2px;
}
/* Title Decoration */
.monaco-workbench > .part.editor > .content > .one-editor-container > .title .title-decoration {
......@@ -34,39 +27,10 @@
/* Title Label */
.monaco-workbench > .part.editor > .content > .one-editor-container > .title .title-label {
line-height: 35px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
position: relative;
flex: 1;
font-style: italic;
}
.monaco-workbench > .part.editor > .content > .one-editor-container > .title.pinned .title-label {
font-style: normal;
}
.monaco-workbench > .part.editor > .content > .one-editor-container > .title .title-label a {
text-decoration: none;
font-size: 13px;
cursor: default;
}
.vs .monaco-workbench > .part.editor > .content > .one-editor-container > .title .title-label a {
color: #333333;
}
.vs .monaco-workbench > .part.editor > .content > .one-editor-container .title.inactive .title-label a {
color: rgba(51, 51, 51, 0.5);
}
.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-container > .title .title-label a {
color: white;
}
.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-container .title.inactive .title-label a {
color: rgba(255, 255, 255, 0.5);
padding-left: 2px;
}
/* Title Description */
......@@ -89,52 +53,9 @@
.monaco-workbench > .part.editor > .content > .one-editor-container > .title .title-actions {
display: flex;
flex: initial;
}
.monaco-workbench > .part.editor > .content > .one-editor-container .title.inactive .title-actions {
opacity: 0.5;
}
.monaco-workbench > .part.editor > .content > .one-editor-container > .title .title-actions .action-label {
display: block;
height: 35px;
width: 28px;
background-size: 16px;
background-position: center center;
background-repeat: no-repeat;
}
.monaco-workbench > .part.editor > .content > .one-editor-container > .title .title-actions .action-label .label {
display: none;
}
/* Drag Cursor */
.monaco-workbench > .part.editor > .content.multiple-editors .one-editor-container .title,
.monaco-workbench > .part.editor > .content.multiple-editors .one-editor-container .title .title-label a,
.monaco-workbench > .part.editor > .content.multiple-editors .one-editor-container .title .title-label span {
cursor: -webkit-grab;
}
#monaco-workbench-editor-move-overlay,
.monaco-workbench > .part.editor > .content.multiple-editors .one-editor-container.dragged,
.monaco-workbench > .part.editor > .content.multiple-editors .one-editor-container.dragged .title,
.monaco-workbench > .part.editor > .content.multiple-editors .one-editor-container.dragged .title .title-label a,
.monaco-workbench > .part.editor > .content.multiple-editors .one-editor-container.dragged .title .title-label span,
.monaco-workbench > .part.editor > .content.multiple-editors .one-editor-container.dragged .monaco-editor .view-lines {
cursor: -webkit-grabbing;
}
.monaco-workbench > .part.editor > .content.multiple-editors.custom-drag-cursor .one-editor-container .title,
.monaco-workbench > .part.editor > .content.multiple-editors.custom-drag-cursor .one-editor-container .title .title-label a,
.monaco-workbench > .part.editor > .content.multiple-editors.custom-drag-cursor .one-editor-container .title .title-label span {
cursor: url(data:;base64,AAACAAEAICACAAcABQAwAQAAFgAAACgAAAAgAAAAQAAAAAEAAQAAAAAAAAEAAAAAAAAAAAAAAgAAAAAAAAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8AAAA/AAAAfwAAAP+AAAH/gAAB/8AAA//AAAd/wAAGf+AAAH9gAADbYAAA2yAAAZsAAAGbAAAAGAAAAAAAAA//////////////////////////////////////////////////////////////////////////////////////gH///4B///8Af//+AD///AA///wAH//4AB//8AAf//AAD//5AA///gAP//4AD//8AF///AB///5A////5///8=), auto;
}
#monaco-workbench-editor-move-overlay-custom-drag-cursor,
.monaco-workbench > .part.editor > .content.multiple-editors.custom-drag-cursor .one-editor-container.dragged,
.monaco-workbench > .part.editor > .content.multiple-editors.custom-drag-cursor .one-editor-container.dragged .title,
.monaco-workbench > .part.editor > .content.multiple-editors.custom-drag-cursor .one-editor-container.dragged .title .title-label a,
.monaco-workbench > .part.editor > .content.multiple-editors.custom-drag-cursor .one-editor-container.dragged .title .title-label span,
.monaco-workbench > .part.editor > .content.multiple-editors.custom-drag-cursor .one-editor-container.dragged .monaco-editor .view-lines {
cursor: url(data:;base64,AAACAAEAICACAAcABQAwAQAAFgAAACgAAAAgAAAAQAAAAAEAAQAAAAAAAAEAAAAAAAAAAAAAAgAAAAAAAAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8AAAA/AAAAfwAAAP+AAAH/gAAB/8AAAH/AAAB/wAAA/0AAANsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////////////////////////////////////////////////////////////////////////////gH///4B///8Af//+AD///AA///wAH//+AB///wAf//4AH//+AD///yT/////////////////////////////8=), auto;
.monaco-workbench > .part.editor > .content > .one-editor-container .title.active .title-actions {
opacity: 1;
}
\ No newline at end of file
......@@ -82,65 +82,4 @@
.monaco-workbench > .editor > .content .editor-container {
height: calc(100% - 35px); /* Editor is below editor title */
}
/* Actions */
.monaco-workbench .close-editor-action {
background: url('close.svg') center center no-repeat;
}
.vs-dark .monaco-workbench .close-editor-action {
background: url('close-inverse.svg') center center no-repeat;
}
.monaco-workbench .split-editor-action {
background: url('split-editor.svg') center center no-repeat;
}
.vs-dark .monaco-workbench .split-editor-action {
background: url('split-editor-inverse.svg') center center no-repeat;
}
.monaco-workbench .show-group-editors-action {
background: url('stackview.svg') center center no-repeat;
}
.vs-dark .monaco-workbench .show-group-editors-action {
background: url('stackview-inverse.svg') center center no-repeat;
}
/* High Contrast Icons */
.hc-black .monaco-workbench .close-editor-action,
.hc-black .monaco-workbench .show-group-editors-action,
.hc-black .monaco-workbench .split-editor-action {
background: none;
}
.hc-black .monaco-workbench .show-group-editors-action:before {
content: url('stackview-inverse.svg');
position: absolute;
top: 12px;
left: 8px;
height: 16px;
width: 16px;
}
.hc-black .monaco-workbench .close-editor-action:before {
content: url('close-inverse.svg');
position: absolute;
top: 12px;
left: 8px;
height: 16px;
width: 16px;
}
.hc-black .monaco-workbench .split-editor-action:before {
content: url('SplitEditor_inverse.svg');
position: absolute;
top: 12px;
left: 8px;
height: 16px;
width: 16px;
}
\ No newline at end of file
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
/* Tabs Container */
.monaco-workbench > .part.editor > .content > .one-editor-container > .title > .monaco-scrollable-element {
flex: 1;
}
.monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container {
display: flex;
overflow: scroll;
background-color: rgba(128, 128, 128, 0.2);
}
.monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container::-webkit-scrollbar {
display: none;
}
/* Tab */
.monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab {
display: flex;
width: 120px;
min-width: fit-content;
overflow: hidden;
white-space: nowrap;
cursor: pointer;
border-left: 1px solid rgba(128, 128, 128, 0.2);
border-bottom: 1px solid rgba(128, 128, 128, 0.2);
box-sizing: border-box;
opacity: 0.7;
padding-left: 10px;
}
.monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab:focus {
outline-offset: -2px;
}
.hc-black .monaco-workbench > .part.editor > .content > .one-editor-container > .title.active .tabs-container > .tab.active {
border: 1px solid #6FC3DF;
}
.monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab:first-child {
border-left: 0;
}
.monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab.active {
border-bottom: 0;
opacity: 1;
}
.vs .monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container.dropfeedback,
.vs .monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab.dropfeedback {
background-color: #DDECFF;
}
.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container.dropfeedback,
.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab.dropfeedback {
background-color: #383B3D;
}
.hc-black .monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container.dropfeedback,
.hc-black .monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab.dropfeedback {
background: none !important;
border: 1px dashed #f38518;
}
.monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab.dragged {
opacity: 0.7;
}
/* Tab Close */
.monaco-workbench > .part.editor > .content > .one-editor-container .title .tabs-container > .tab > .tab-close {
margin-top: auto;
margin-bottom: auto;
width: 28px;
}
.monaco-workbench > .part.editor > .content > .one-editor-container .title.active .tabs-container > .tab.active > .tab-close .action-label, /* always show it for active tab */
.monaco-workbench > .part.editor > .content > .one-editor-container .title.active .tabs-container > .tab > .tab-close .action-label:focus, /* always show it on focus */
.monaco-workbench > .part.editor > .content > .one-editor-container .title.active .tabs-container > .tab:hover > .tab-close .action-label, /* always show it on hover */
.monaco-workbench > .part.editor > .content > .one-editor-container .title.active .tabs-container > .tab.active:hover > .tab-close .action-label, /* always show it on hover */
.monaco-workbench > .part.editor > .content > .one-editor-container .title .tabs-container > .tab.dirty > .tab-close .action-label { /* always show it for dirty tabs */
opacity: 1;
}
.monaco-workbench > .part.editor > .content > .one-editor-container .title .tabs-container > .tab.active > .tab-close .action-label, /* show dimmed for inactive group */
.monaco-workbench > .part.editor > .content > .one-editor-container .title .tabs-container > .tab.active:hover > .tab-close .action-label { /* show dimmed for inactive group */
opacity: 0.5;
}
.monaco-workbench > .part.editor > .content > .one-editor-container .title .tabs-container > .tab:hover > .tab-close .action-label { /* show more dimmed for inactive group and tab */
opacity: 0.4;
}
.monaco-workbench > .part.editor > .content > .one-editor-container .title .tabs-container > .tab > .tab-close .action-label {
opacity: 0;
display: block;
height: 16px;
width: 16px;
background-size: 16px;
background-position: center center;
background-repeat: no-repeat;
margin-right: 0.5em;
}
.vs .monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab.dirty .close-editor-action {
background: url('close-dirty.svg') center center no-repeat;
}
.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab.dirty .close-editor-action {
background: url('close-dirty-inverse.svg') center center no-repeat;
}
.vs .monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab.dirty .close-editor-action:hover {
background: url('close.svg') center center no-repeat;
}
.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab.dirty .close-editor-action:hover {
background: url('close-inverse.svg') center center no-repeat;
}
.hc-black .monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab.dirty .close-editor-action,
.hc-black .monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab.dirty .close-editor-action:hover {
background: none;
}
.hc-black .monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab.dirty .close-editor-action:before {
content: url('close-dirty-inverse.svg');
position: absolute;
top: 10px;
left: 4px;
height: 16px;
width: 16px;
}
.hc-black .monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab.dirty .close-editor-action:hover:before {
content: url('close-inverse.svg');
position: absolute;
top: 10px;
left: 4px;
height: 16px;
width: 16px;
}
/* Group Actions */
.monaco-workbench > .part.editor > .content > .one-editor-container > .title .group-actions {
flex: initial;
padding-left: 4px;
background-color: rgba(128, 128, 128, 0.2);
}
\ No newline at end of file
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
/* Editor Label */
.monaco-workbench > .part.editor > .content > .one-editor-container > .title .title-label,
.monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab .tab-label {
line-height: 35px;
white-space: nowrap;
flex: 1;
font-style: italic;
}
.monaco-workbench > .part.editor > .content > .one-editor-container > .title.pinned .title-label,
.monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab.pinned .tab-label {
font-style: normal;
}
.monaco-workbench > .part.editor > .content > .one-editor-container > .title .title-label a,
.monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab .tab-label a {
text-decoration: none;
font-size: 13px;
cursor: pointer;
}
.vs .monaco-workbench > .part.editor > .content > .one-editor-container > .title .title-label a,
.vs .monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab .tab-label a {
color: rgba(51, 51, 51, 0.5);
}
.vs .monaco-workbench > .part.editor > .content > .one-editor-container .title.active .title-label a,
.vs .monaco-workbench > .part.editor > .content > .one-editor-container .title.active .tabs-container > .tab .tab-label a {
color: #333333;
}
.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-container > .title .title-label a,
.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab .tab-label a {
color: rgba(255, 255, 255, 0.5);
}
.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-container .title.active .title-label a,
.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-container .title.active .tabs-container > .tab .tab-label a {
color: white;
}
/* Title Actions */
.monaco-workbench > .part.editor > .content > .one-editor-container > .title .title-actions .action-label,
.monaco-workbench > .part.editor > .content > .one-editor-container > .title .group-actions .action-label {
display: block;
height: 35px;
width: 28px;
background-size: 16px;
background-position: center center;
background-repeat: no-repeat;
}
.monaco-workbench > .part.editor > .content > .one-editor-container > .title .group-actions .action-label .label,
.monaco-workbench > .part.editor > .content > .one-editor-container > .title .title-actions .action-label .label {
display: none;
}
/* Drag Cursor */
.monaco-workbench > .part.editor > .content.multiple-editors .one-editor-container .title,
.monaco-workbench > .part.editor > .content.multiple-editors .one-editor-container .title .title-label a,
.monaco-workbench > .part.editor > .content.multiple-editors .one-editor-container .title .title-label span {
cursor: -webkit-grab;
}
#monaco-workbench-editor-move-overlay,
.monaco-workbench > .part.editor > .content.multiple-editors .one-editor-container.dragged,
.monaco-workbench > .part.editor > .content.multiple-editors .one-editor-container.dragged .title,
.monaco-workbench > .part.editor > .content.multiple-editors .one-editor-container.dragged .title .title-label a,
.monaco-workbench > .part.editor > .content.multiple-editors .one-editor-container.dragged .title .title-label span,
.monaco-workbench > .part.editor > .content.multiple-editors .one-editor-container.dragged .monaco-editor .view-lines {
cursor: -webkit-grabbing;
}
.monaco-workbench > .part.editor > .content.multiple-editors.custom-drag-cursor .one-editor-container .title,
.monaco-workbench > .part.editor > .content.multiple-editors.custom-drag-cursor .one-editor-container .title .title-label a,
.monaco-workbench > .part.editor > .content.multiple-editors.custom-drag-cursor .one-editor-container .title .title-label span {
cursor: url(data:;base64,AAACAAEAICACAAcABQAwAQAAFgAAACgAAAAgAAAAQAAAAAEAAQAAAAAAAAEAAAAAAAAAAAAAAgAAAAAAAAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8AAAA/AAAAfwAAAP+AAAH/gAAB/8AAA//AAAd/wAAGf+AAAH9gAADbYAAA2yAAAZsAAAGbAAAAGAAAAAAAAA//////////////////////////////////////////////////////////////////////////////////////gH///4B///8Af//+AD///AA///wAH//4AB//8AAf//AAD//5AA///gAP//4AD//8AF///AB///5A////5///8=), auto;
}
#monaco-workbench-editor-move-overlay-custom-drag-cursor,
.monaco-workbench > .part.editor > .content.multiple-editors.custom-drag-cursor .one-editor-container.dragged,
.monaco-workbench > .part.editor > .content.multiple-editors.custom-drag-cursor .one-editor-container.dragged .title,
.monaco-workbench > .part.editor > .content.multiple-editors.custom-drag-cursor .one-editor-container.dragged .title .title-label a,
.monaco-workbench > .part.editor > .content.multiple-editors.custom-drag-cursor .one-editor-container.dragged .title .title-label span,
.monaco-workbench > .part.editor > .content.multiple-editors.custom-drag-cursor .one-editor-container.dragged .monaco-editor .view-lines {
cursor: url(data:;base64,AAACAAEAICACAAcABQAwAQAAFgAAACgAAAAgAAAAQAAAAAEAAQAAAAAAAAEAAAAAAAAAAAAAAgAAAAAAAAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8AAAA/AAAAfwAAAP+AAAH/gAAB/8AAAH/AAAB/wAAA/0AAANsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////////////////////////////////////////////////////////////////////////////gH///4B///8Af//+AD///AA///wAH//+AB///wAf//4AH//+AD///yT/////////////////////////////8=), auto;
}
/* Actions */
.monaco-workbench .close-editor-action {
background: url('close.svg') center center no-repeat;
}
.vs-dark .monaco-workbench .close-editor-action {
background: url('close-inverse.svg') center center no-repeat;
}
.monaco-workbench .split-editor-action {
background: url('split-editor.svg') center center no-repeat;
}
.vs-dark .monaco-workbench .split-editor-action {
background: url('split-editor-inverse.svg') center center no-repeat;
}
.monaco-workbench .show-group-editors-action {
background: url('stackview.svg') center center no-repeat;
}
.vs-dark .monaco-workbench .show-group-editors-action {
background: url('stackview-inverse.svg') center center no-repeat;
}
/* High Contrast Icons */
.hc-black .monaco-workbench .close-editor-action,
.hc-black .monaco-workbench .show-group-editors-action,
.hc-black .monaco-workbench .split-editor-action {
background: none;
}
.hc-black .monaco-workbench .show-group-editors-action:before {
content: url('stackview-inverse.svg');
position: absolute;
top: 12px;
left: 8px;
height: 16px;
width: 16px;
}
.hc-black .monaco-workbench .close-editor-action:before {
content: url('close-inverse.svg');
position: absolute;
top: 10px;
left: 4px;
height: 16px;
width: 16px;
}
.hc-black .monaco-workbench .split-editor-action:before {
content: url('split-editor-inverse.svg');
position: absolute;
top: 12px;
left: 8px;
height: 16px;
width: 16px;
}
\ No newline at end of file
......@@ -125,16 +125,12 @@ export class NoTabsTitleControl extends TitleControl {
}
// Focus editor group unless click on toolbar
else if (this.stacks.groups.length === 1 && !this.targetInToolbar(<any>e.target || e.srcElement)) {
else if (this.stacks.groups.length === 1 && !DOM.isAncestor(<any>e.target || e.srcElement, this.editorActionsToolbar.getContainer().getHTMLElement())) {
this.editorGroupService.focusGroup(position);
}
}
private targetInToolbar(target: HTMLElement): boolean {
return DOM.isAncestor(target, this.editorActionsToolbar.getContainer().getHTMLElement());
}
public refresh(): void {
protected doRefresh(): void {
if (!this.context) {
return;
}
......@@ -162,9 +158,9 @@ export class NoTabsTitleControl extends TitleControl {
// Activity state
if (isActive) {
this.titleContainer.removeClass('inactive');
this.titleContainer.addClass('active');
} else {
this.titleContainer.addClass('inactive');
this.titleContainer.removeClass('active');
}
// Editor Title
......@@ -194,7 +190,6 @@ export class NoTabsTitleControl extends TitleControl {
if (isActive && editor instanceof EditorInput && editor.supportsSplitEditor()) {
primaryEditorActions.push(this.splitEditorAction);
}
primaryEditorActions.push(this.closeEditorAction);
const secondaryEditorActions = prepareActions(editorActions.secondary);
const primaryEditorActionIds = primaryEditorActions.map(a => a.id);
......@@ -202,6 +197,8 @@ export class NoTabsTitleControl extends TitleControl {
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;
}
......
......@@ -23,11 +23,13 @@ import {IEditorGroupService} from 'vs/workbench/services/group/common/groupServi
import {IEventService} from 'vs/platform/event/common/event';
import {IMessageService} from 'vs/platform/message/common/message';
import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry';
import {IConfigurationService} from 'vs/platform/configuration/common/configuration';
import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation';
import {IKeybindingService} from 'vs/platform/keybinding/common/keybindingService';
import {IDisposable, dispose} from 'vs/base/common/lifecycle';
import {TabsTitleControl} from 'vs/workbench/browser/parts/editor/tabsTitleControl';
import {NoTabsTitleControl} from 'vs/workbench/browser/parts/editor/noTabsTitleControl';
import {IEditorStacksModel} from 'vs/workbench/common/editor';
import {IEditorStacksModel, IStacksModelChangeEvent, IWorkbenchEditorConfiguration} from 'vs/workbench/common/editor';
import {ITitleAreaControl} from 'vs/workbench/browser/parts/editor/titleControl';
export enum Rochade {
......@@ -120,6 +122,7 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti
@ITelemetryService private telemetryService: ITelemetryService,
@IContextMenuService private contextMenuService: IContextMenuService,
@IEventService private eventService: IEventService,
@IConfigurationService private configurationService: IConfigurationService,
@IKeybindingService private keybindingService: IKeybindingService,
@IInstantiationService private instantiationService: IInstantiationService
) {
......@@ -149,13 +152,45 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti
}
private registerListeners(): void {
this.toDispose.push(this.stacks.onModelChanged(() => this.onStacksChanged()));
this.toDispose.push(this.stacks.onModelChanged(e => this.onStacksChanged(e)));
this.toDispose.push(this.configurationService.onDidUpdateConfiguration(e => this.onConfigurationUpdated(e.config)));
}
private onStacksChanged(): void {
private onConfigurationUpdated(configuration: IWorkbenchEditorConfiguration): void {
POSITIONS.forEach(position => {
const titleControl = this.titleAreaControl[position];
if (titleControl) {
const usingTabs = (titleControl instanceof TabsTitleControl);
const useTabs = configuration.workbench.showTabs;
if (usingTabs !== useTabs) {
// Dispose old
titleControl.dispose();
this.titleContainer[position].empty();
// Create new
this.createTitleControl(position);
}
}
});
}
private onStacksChanged(e: IStacksModelChangeEvent): void {
// Up to date context
POSITIONS.forEach(position => {
this.titleAreaControl[position].setContext(this.stacks.groupAt(position));
});
// Refresh / update if group is visible and has a position
const position = this.stacks.positionOfGroup(e.group);
if (position >= 0) {
if (e.structural) {
this.titleAreaControl[position].refresh();
} else {
this.titleAreaControl[position].update();
}
}
}
public get onGroupFocusChanged(): Event<void> {
......@@ -699,9 +734,8 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti
this.titleContainer[position] = $(this.containers[position]).div({ 'class': 'title' });
this.hookTitleDragListener(position);
this.titleAreaControl[position] = this.instantiationService.createInstance(NoTabsTitleControl);
this.titleAreaControl[position].create($(this.titleContainer[position]));
this.titleAreaControl[position].setContext(this.stacks.groupAt(position));
// Title Control
this.createTitleControl(position);
});
// Progress Bars per position
......@@ -716,17 +750,29 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti
}
}
private createTitleControl(position: Position): void {
const useTabs = !!this.configurationService.getConfiguration<IWorkbenchEditorConfiguration>().workbench.showTabs;
this.titleAreaControl[position] = useTabs ? this.instantiationService.createInstance(TabsTitleControl) : this.instantiationService.createInstance(NoTabsTitleControl);
this.titleAreaControl[position].create($(this.titleContainer[position]));
this.titleAreaControl[position].setContext(this.stacks.groupAt(position));
this.titleAreaControl[position].refresh(true);
}
private hookTitleDragListener(position: Position): void {
let wasDragged = false;
// Allow to reorder positions by dragging the title
this.titleContainer[position].on(DOM.EventType.MOUSE_DOWN, (e: MouseEvent) => {
if (!this.titleAreaControl[position].allowDragging(<any>e.target || e.srcElement)) {
return; // return early if we are not in the drag zone of the title widget
}
// Reset flag
wasDragged = false;
// Return early if there is only one editor active or the user clicked into the toolbar
if (this.getVisibleEditorCount() <= 1 || !!DOM.findParentWithClass((<any>e.target || e.srcElement), 'monaco-action-bar', 'one-editor-container')) {
if (this.getVisibleEditorCount() <= 1) {
return;
}
......@@ -890,8 +936,8 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti
// Move to valid position if any
if (moveTo !== null) {
this.editorGroupService.moveGroup(position, moveTo);
this.titleAreaControl[position].refresh();
this.titleAreaControl[moveTo].refresh();
this.titleAreaControl[position].refresh(true);
this.titleAreaControl[moveTo].refresh(true);
}
// Otherwise layout to restore proper positioning
......@@ -1272,10 +1318,15 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti
}
});
// Layout active editors
// Layout visible editors
POSITIONS.forEach(position => {
this.layoutEditor(position);
});
// Layout title controls
POSITIONS.forEach(position => {
this.titleAreaControl[position].layout();
});
}
private layoutEditor(position: Position): void {
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'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';
import arrays = require('vs/base/common/arrays');
import errors = require('vs/base/common/errors');
import DOM = require('vs/base/browser/dom');
import {Builder, $} from 'vs/base/browser/builder';
import {MIME_BINARY} from 'vs/base/common/mime';
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} from 'vs/base/common/keyCodes';
import {ActionBar, Separator} from 'vs/base/browser/ui/actionbar/actionbar';
import {StandardMouseEvent} from 'vs/base/browser/mouseEvent';
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 {IMessageService} from 'vs/platform/message/common/message';
import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry';
import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation';
import {IKeybindingService} from 'vs/platform/keybinding/common/keybindingService';
import {TitleControl} from 'vs/workbench/browser/parts/editor/titleControl';
import {IDisposable, dispose} from 'vs/base/common/lifecycle';
import {ScrollableElement} from 'vs/base/browser/ui/scrollbar/scrollableElement';
import {ScrollbarVisibility} from 'vs/base/browser/ui/scrollbar/scrollableElementOptions';
export class TabsTitleControl extends TitleControl {
private static draggedEditor: IEditorIdentifier;
private titleContainer: HTMLElement;
private tabsContainer: HTMLElement;
private activeTab: HTMLElement;
private scrollbar: ScrollableElement;
private groupActionsToolbar: ToolBar;
private tabDisposeables: IDisposable[];
private currentPrimaryGroupActionIds: string[];
private currentSecondaryGroupActionIds: string[];
constructor(
@IContextMenuService contextMenuService: IContextMenuService,
@IInstantiationService instantiationService: IInstantiationService,
@IWorkbenchEditorService editorService: IWorkbenchEditorService,
@IEditorGroupService editorGroupService: IEditorGroupService,
@IKeybindingService keybindingService: IKeybindingService,
@ITelemetryService telemetryService: ITelemetryService,
@IMessageService messageService: IMessageService
) {
super(contextMenuService, instantiationService, editorService, editorGroupService, keybindingService, telemetryService, messageService);
this.currentPrimaryGroupActionIds = [];
this.currentSecondaryGroupActionIds = [];
this.tabDisposeables = [];
}
public setContext(group: IEditorGroup): void {
super.setContext(group);
this.groupActionsToolbar.context = { group };
}
public create(parent: Builder): void {
this.titleContainer = parent.getHTMLElement();
// Tabs Container
this.tabsContainer = document.createElement('div');
DOM.addClass(this.tabsContainer, 'tabs-container');
// Custom Scrollbar
this.scrollbar = new ScrollableElement(this.tabsContainer, {
horizontal: ScrollbarVisibility.Auto,
vertical: ScrollbarVisibility.Hidden,
scrollYToX: true,
useShadows: false,
canUseTranslate3d: true,
horizontalScrollbarSize: 3
});
this.tabsContainer.style.overflow = 'scroll'; // custom scrollbar is eager on removing this style but we want it for DND scroll feedback
this.scrollbar.onScroll(e => {
this.tabsContainer.scrollLeft = e.scrollLeft;
});
this.titleContainer.appendChild(this.scrollbar.getDomNode());
// Drag over
this.toDispose.push(DOM.addDisposableListener(this.tabsContainer, DOM.EventType.DRAG_OVER, (e: DragEvent) => {
const target = e.target;
if (target instanceof HTMLElement && target.className.indexOf('tabs-container') === 0) {
DOM.addClass(this.tabsContainer, 'dropfeedback');
}
}));
// Drag leave
this.toDispose.push(DOM.addDisposableListener(this.tabsContainer, DOM.EventType.DRAG_LEAVE, (e: DragEvent) => {
DOM.removeClass(this.tabsContainer, 'dropfeedback');
}));
// Drag end
this.toDispose.push(DOM.addDisposableListener(this.tabsContainer, DOM.EventType.DRAG_END, (e: DragEvent) => {
DOM.removeClass(this.tabsContainer, 'dropfeedback');
}));
// Drop onto tabs container
this.toDispose.push(DOM.addDisposableListener(this.tabsContainer, DOM.EventType.DROP, (e: DragEvent) => {
DOM.removeClass(this.tabsContainer, 'dropfeedback');
const target = e.target;
if (target instanceof HTMLElement && target.className.indexOf('tabs-container') === 0) {
const group = this.context;
if (group) {
if (TabsTitleControl.draggedEditor) {
e.preventDefault();
const sourcePosition = this.stacks.positionOfGroup(TabsTitleControl.draggedEditor.group);
const targetPosition = this.stacks.positionOfGroup(group);
// Move editor to target position at the end
this.editorGroupService.moveEditor(TabsTitleControl.draggedEditor.editor, sourcePosition, targetPosition, group.count);
}
}
}
}));
// Group Actions
const groupActionsContainer = document.createElement('div');
DOM.addClass(groupActionsContainer, 'group-actions');
this.titleContainer.appendChild(groupActionsContainer);
this.groupActionsToolbar = this.doCreateToolbar($(groupActionsContainer));
}
public allowDragging(element: HTMLElement): boolean {
return (element.className === 'tabs-container');
}
protected doUpdate(): void {
if (!this.context) {
return;
}
const group = this.context;
// Tabs container activity state
const isActive = this.stacks.isActive(group);
if (isActive) {
DOM.addClass(this.titleContainer, 'active');
} else {
DOM.removeClass(this.titleContainer, 'active');
}
// Tab styles
this.context.getEditors().forEach((editor, index) => {
const tabContainer = this.tabsContainer.children[index];
if (tabContainer instanceof HTMLElement) {
const isPinned = group.isPinned(editor);
const isActive = group.isActive(editor);
const isDirty = editor.isDirty();
// Pinned state
if (isPinned) {
DOM.addClass(tabContainer, 'pinned');
} else {
DOM.removeClass(tabContainer, 'pinned');
}
// Active state
if (isActive) {
DOM.addClass(tabContainer, 'active');
this.activeTab = tabContainer;
} else {
DOM.removeClass(tabContainer, 'active');
}
// Dirty State
if (isDirty) {
DOM.addClass(tabContainer, 'dirty');
} else {
DOM.removeClass(tabContainer, 'dirty');
}
}
});
// Ensure active tab is always revealed
this.layout();
}
protected doRefresh(): void {
if (!this.context) {
return;
}
const group = this.context;
const editor = group.activeEditor;
if (!editor) {
this.groupActionsToolbar.setActions([], [])();
this.currentPrimaryGroupActionIds = [];
this.currentSecondaryGroupActionIds = [];
return; // return early if we are being closed
}
// Refresh Group 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.groupActionsToolbar.setActions(primaryGroupActions, secondaryGroupActions)();
this.currentPrimaryGroupActionIds = primaryGroupActionIds;
this.currentSecondaryGroupActionIds = secondaryGroupActionIds;
}
// Refresh Tabs
this.refreshTabs(group);
// Update styles
this.doUpdate();
}
private refreshTabs(group: IEditorGroup): void {
// Empty container first
DOM.clearNode(this.tabsContainer);
dispose(this.tabDisposeables);
this.tabDisposeables = [];
const tabContainers: HTMLElement[] = [];
// Add a tab for each opened editor
this.context.getEditors().forEach(editor => {
const tabContainer = document.createElement('div');
tabContainer.draggable = true;
tabContainer.tabIndex = 0;
DOM.addClass(tabContainer, 'tab monaco-editor-background');
tabContainers.push(tabContainer);
// Tab Label Container
const tabLabelContainer = document.createElement('div');
tabContainer.appendChild(tabLabelContainer);
DOM.addClass(tabLabelContainer, 'tab-label');
// Tab Label
const tabLabel = document.createElement('a');
tabLabel.innerText = editor.getName();
tabLabel.title = editor.getDescription(true) || '';
tabLabelContainer.appendChild(tabLabel);
// Tab Close
const tabCloseContainer = document.createElement('div');
DOM.addClass(tabCloseContainer, 'tab-close');
tabContainer.appendChild(tabCloseContainer);
const bar = new ActionBar(tabCloseContainer, { context: { editor, group }, ariaLabel: nls.localize('araLabelTabActions', "Tab actions") });
bar.push(this.closeEditorAction, { icon: true, label: false });
this.tabDisposeables.push(bar);
// Eventing
this.hookTabListeners(tabContainer, { editor, group });
});
// Add to tabs container
tabContainers.forEach(tab => this.tabsContainer.appendChild(tab));
}
public layout(): void {
if (!this.activeTab) {
return;
}
const visibleContainerWidth = this.tabsContainer.offsetWidth;
const totalContainerWidth = this.tabsContainer.scrollWidth;
// Update scrollbar
this.scrollbar.updateState({
width: visibleContainerWidth,
scrollWidth: totalContainerWidth
});
// Always reveal the active one
const containerScrollPosX = this.tabsContainer.scrollLeft;
const activeTabPosX = this.activeTab.offsetLeft;
const activeTabWidth = this.activeTab.offsetWidth;
// Tab is overflowing to the right: Scroll minimally until the element is fully visible to the right
if (containerScrollPosX + visibleContainerWidth < activeTabPosX + activeTabWidth) {
this.scrollbar.updateState({
scrollLeft: containerScrollPosX + ((activeTabPosX + activeTabWidth) /* right corner of tab */ - (containerScrollPosX + visibleContainerWidth) /* right corner of view port */)
});
}
// Tab is overlflowng to the left: Scroll it into view to the left
else if (containerScrollPosX > activeTabPosX) {
this.scrollbar.updateState({
scrollLeft: this.activeTab.offsetLeft
});
}
// Update enablement of certain actions that depend on overflow
const isOverflowing = (totalContainerWidth > visibleContainerWidth);
this.showEditorsOfLeftGroup.enabled = isOverflowing;
this.showEditorsOfCenterGroup.enabled = isOverflowing;
this.showEditorsOfRightGroup.enabled = isOverflowing;
}
private hookTabListeners(tab: HTMLElement, identifier: IEditorIdentifier): void {
const {editor, group} = identifier;
const position = this.stacks.positionOfGroup(group);
// Open on Click
this.tabDisposeables.push(DOM.addDisposableListener(tab, DOM.EventType.MOUSE_DOWN, (e: MouseEvent) => {
if (e.button === 0 /* Left Button */ && !DOM.findParentWithClass(<any>e.target || e.srcElement, 'monaco-action-bar', 'tab')) {
this.editorService.openEditor(editor, null, position).done(null, errors.onUnexpectedError);
}
}));
// Open on Keyboard Enter/Space
this.tabDisposeables.push(DOM.addDisposableListener(tab, DOM.EventType.KEY_UP, (e: KeyboardEvent) => {
const event = new StandardKeyboardEvent(e);
// Run action on Enter/Space
if (event.equals(CommonKeybindings.ENTER) || event.equals(CommonKeybindings.SPACE)) {
this.editorService.openEditor(editor, null, position).done(null, errors.onUnexpectedError);
event.preventDefault();
event.stopPropagation();
}
}));
// Pin on double click
this.tabDisposeables.push(DOM.addDisposableListener(tab, DOM.EventType.DBLCLICK, (e: MouseEvent) => {
DOM.EventHelper.stop(e);
this.editorGroupService.pinEditor(position, editor);
}));
// Close on mouse middle click
this.tabDisposeables.push(DOM.addDisposableListener(tab, DOM.EventType.MOUSE_UP, (e: MouseEvent) => {
DOM.EventHelper.stop(e);
if (e.button === 1 /* Middle Button */) {
this.editorService.closeEditor(position, editor).done(null, errors.onUnexpectedError);
}
}));
// 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;
}
});
}));
// Drag start
this.tabDisposeables.push(DOM.addDisposableListener(tab, DOM.EventType.DRAG_START, (e: DragEvent) => {
DOM.addClass(tab, 'dragged');
TabsTitleControl.draggedEditor = { editor, group };
e.dataTransfer.effectAllowed = 'move';
// Enable support to drag a file to desktop
const fileInput = asFileEditorInput(editor, true);
if (fileInput) {
e.dataTransfer.setData('DownloadURL', [MIME_BINARY, editor.getName(), fileInput.getResource().toString()].join(':'));
}
}));
// Drag over
this.tabDisposeables.push(DOM.addDisposableListener(tab, DOM.EventType.DRAG_OVER, (e: DragEvent) => {
DOM.addClass(tab, 'dropfeedback');
}));
// Drag leave
this.tabDisposeables.push(DOM.addDisposableListener(tab, DOM.EventType.DRAG_LEAVE, (e: DragEvent) => {
DOM.removeClass(tab, 'dropfeedback');
}));
// Drag end
this.tabDisposeables.push(DOM.addDisposableListener(tab, DOM.EventType.DRAG_END, (e: DragEvent) => {
DOM.removeClass(tab, 'dragged');
DOM.removeClass(tab, 'dropfeedback');
TabsTitleControl.draggedEditor = void 0;
}));
// Drop
this.tabDisposeables.push(DOM.addDisposableListener(tab, DOM.EventType.DROP, (e: DragEvent) => {
if (TabsTitleControl.draggedEditor) {
e.preventDefault();
const sourcePosition = this.stacks.positionOfGroup(TabsTitleControl.draggedEditor.group);
const targetPosition = this.stacks.positionOfGroup(group);
const targetIndex = group.indexOf(editor);
// Move editor to target position and index
this.editorGroupService.moveEditor(TabsTitleControl.draggedEditor.editor, sourcePosition, targetPosition, targetIndex);
}
}));
}
private getTabActions(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,
this.closeRightEditorsAction,
new Separator(),
this.pinEditorAction,
];
// Actions: For active editor
if (group.isActive(editor)) {
const editorActions = this.getEditorActions(group);
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.groupActionsToolbar.dispose();
}
}
\ No newline at end of file
......@@ -5,12 +5,14 @@
'use strict';
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 {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 {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';
......@@ -26,7 +28,9 @@ import {QuickOpenAction} from 'vs/workbench/browser/quickopen';
import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry';
import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation';
import {IKeybindingService} from 'vs/platform/keybinding/common/keybindingService';
import {ShowEditorsInLeftGroupAction, ShowAllEditorsAction, ShowEditorsInCenterGroupAction, ShowEditorsInRightGroupAction, CloseEditorsInGroupAction, MoveGroupLeftAction, MoveGroupRightAction, SplitEditorAction, CloseEditorAction} from 'vs/workbench/browser/parts/editor/editorActions';
import {ShowEditorsInLeftGroupAction, ShowAllEditorsAction, ShowEditorsInCenterGroupAction, ShowEditorsInRightGroupAction, CloseEditorsInGroupAction, MoveGroupLeftAction,
MoveGroupRightAction, SplitEditorAction, CloseEditorAction, PinEditorAction, CloseOtherEditorsInGroupAction, CloseRightEditorsInGroupAction}
from 'vs/workbench/browser/parts/editor/editorActions';
import {IDisposable, dispose} from 'vs/base/common/lifecycle';
export interface IToolbarActions {
......@@ -36,16 +40,23 @@ export interface IToolbarActions {
export interface ITitleAreaControl {
setContext(group: IEditorGroup): void;
allowDragging(element: HTMLElement): boolean;
create(parent: Builder): void;
refresh(): void;
refresh(instant?: boolean): void;
update(instant?: boolean): void;
layout(): void;
dispose(): void;
}
export abstract class TitleControl {
protected stacks: IEditorStacksModel;
protected context: IEditorGroup;
protected toDispose: IDisposable[];
protected closeEditorAction: CloseEditorAction;
protected pinEditorAction: PinEditorAction;
protected closeOtherEditorsAction: CloseOtherEditorsInGroupAction;
protected closeRightEditorsAction: CloseRightEditorsInGroupAction;
protected showEditorsOfLeftGroup: QuickOpenAction;
protected showEditorsOfCenterGroup: QuickOpenAction;
protected showEditorsOfRightGroup: QuickOpenAction;
......@@ -56,9 +67,8 @@ export abstract class TitleControl {
protected showAllEditorsAction: ShowAllEditorsAction;
private mapActionsToEditors: { [editorId: string]: IToolbarActions; };
private scheduler: RunOnceScheduler;
protected toDispose: IDisposable[];
private refreshScheduled: boolean;
constructor(
@IContextMenuService protected contextMenuService: IContextMenuService,
......@@ -73,27 +83,70 @@ export abstract class TitleControl {
this.stacks = editorGroupService.getStacksModel();
this.mapActionsToEditors = Object.create(null);
this.scheduler = new RunOnceScheduler(() => this.refresh(), 0);
this.scheduler = new RunOnceScheduler(() => this.onSchedule(), 0);
this.toDispose.push(this.scheduler);
this.initActions();
}
private onSchedule(): void {
if (this.refreshScheduled) {
this.doRefresh();
} else {
this.doUpdate();
}
this.refreshScheduled = false;
}
public setContext(group: IEditorGroup): void {
this.context = group;
}
public update(instant?: boolean): void {
if (instant) {
this.scheduler.cancel();
this.onSchedule();
} else {
this.scheduler.schedule();
}
}
public refresh(instant?: boolean) {
this.refreshScheduled = true;
this.scheduler.schedule();
if (instant) {
this.scheduler.cancel();
this.onSchedule();
} else {
this.scheduler.schedule();
}
}
public abstract refresh();
protected abstract doRefresh(): void;
protected doUpdate(): void {
this.doRefresh();
}
public layout(): void {
// Subclasses can opt in to react on layout
}
public allowDragging(element: HTMLElement): boolean {
return !DOM.findParentWithClass(element, 'monaco-action-bar', 'one-editor-container');
}
private initActions(): void {
this.closeEditorAction = this.instantiationService.createInstance(CloseEditorAction, CloseEditorAction.ID, nls.localize('close', "Close"));
this.closeOtherEditorsAction = this.instantiationService.createInstance(CloseOtherEditorsInGroupAction, CloseOtherEditorsInGroupAction.ID, nls.localize('closeOthers', "Close Others"));
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(PinEditorAction, PinEditorAction.ID, nls.localize('pin', "Pin Editor"));
this.showAllEditorsAction = this.instantiationService.createInstance(ShowAllEditorsAction, ShowAllEditorsAction.ID, nls.localize('showEditors', "Show 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.closeEditorsInGroupAction = this.instantiationService.createInstance(CloseEditorsInGroupAction, CloseEditorsInGroupAction.ID, nls.localize('closeAll', "Close All"));
this.showEditorsOfLeftGroup = this.instantiationService.createInstance(ShowEditorsInLeftGroupAction, ShowEditorsInLeftGroupAction.ID, nls.localize('showEditors', "Show Editors"));
this.showEditorsOfCenterGroup = this.instantiationService.createInstance(ShowEditorsInCenterGroupAction, ShowEditorsInCenterGroupAction.ID, nls.localize('showEditors', "Show Editors"));
this.showEditorsOfRightGroup = this.instantiationService.createInstance(ShowEditorsInRightGroupAction, ShowEditorsInRightGroupAction.ID, nls.localize('showEditors', "Show Editors"));
......@@ -185,9 +238,9 @@ export abstract class TitleControl {
return { primary, secondary };
}
protected getEditorActionsForContext(context: BaseEditor): IToolbarActions;
protected getEditorActionsForContext(context: IEditorInputActionContext): IToolbarActions;
protected getEditorActionsForContext(context: any): IToolbarActions {
private getEditorActionsForContext(context: BaseEditor): IToolbarActions;
private getEditorActionsForContext(context: IEditorInputActionContext): IToolbarActions;
private getEditorActionsForContext(context: any): IToolbarActions {
let primaryActions: IAction[] = [];
let secondaryActions: IAction[] = [];
......@@ -212,34 +265,30 @@ export abstract class TitleControl {
const editor = group.activeEditor;
const primary: IAction[] = [];
const isOverflowing = group.count > 1;
const groupCount = this.stacks.groups.length;
// Overflow
if (isOverflowing) {
let overflowAction: Action;
if (groupCount === 1) {
overflowAction = this.showAllEditorsAction;
} else {
switch (this.stacks.positionOfGroup(group)) {
case Position.LEFT:
overflowAction = this.showEditorsOfLeftGroup;
break;
case Position.CENTER:
overflowAction = (groupCount === 2) ? this.showEditorsOfRightGroup : this.showEditorsOfCenterGroup;
break;
case Position.RIGHT:
overflowAction = this.showEditorsOfRightGroup;
break;
}
let overflowAction: Action;
if (groupCount === 1) {
overflowAction = this.showAllEditorsAction;
} else {
switch (this.stacks.positionOfGroup(group)) {
case Position.LEFT:
overflowAction = this.showEditorsOfLeftGroup;
break;
case Position.CENTER:
overflowAction = (groupCount === 2) ? this.showEditorsOfRightGroup : this.showEditorsOfCenterGroup;
break;
case Position.RIGHT:
overflowAction = this.showEditorsOfRightGroup;
break;
}
primary.push(overflowAction);
}
primary.push(overflowAction);
// Splitting
if (editor instanceof EditorInput && editor.supportsSplitEditor()) {
primary.push(this.splitEditorAction);
......@@ -283,9 +332,12 @@ export abstract class TitleControl {
this.showEditorsOfCenterGroup,
this.showEditorsOfRightGroup,
this.closeEditorAction,
this.closeRightEditorsAction,
this.closeOtherEditorsAction,
this.closeEditorsInGroupAction,
this.moveGroupLeftAction,
this.moveGroupRightAction,
this.closeEditorsInGroupAction
this.pinEditorAction
].forEach((action) => {
action.dispose();
});
......
......@@ -657,4 +657,14 @@ export interface IEditorIdentifier {
editor: IEditorInput;
}
export type GroupIdentifier = number;
\ No newline at end of file
export interface IEditorContext extends IEditorIdentifier {
event: any;
}
export type GroupIdentifier = number;
export interface IWorkbenchEditorConfiguration {
workbench: {
showTabs: boolean;
};
}
\ No newline at end of file
......@@ -626,6 +626,7 @@ export class EditorStacksModel implements IEditorStacksModel {
private _onGroupClosed: Emitter<EditorGroup>;
private _onGroupMoved: Emitter<EditorGroup>;
private _onGroupActivated: Emitter<EditorGroup>;
private _onGroupDeactivated: Emitter<EditorGroup>;
private _onGroupRenamed: Emitter<EditorGroup>;
private _onEditorDisposed: Emitter<EditorIdentifier>;
private _onEditorDirty: Emitter<EditorIdentifier>;
......@@ -647,13 +648,14 @@ export class EditorStacksModel implements IEditorStacksModel {
this._onGroupOpened = new Emitter<EditorGroup>();
this._onGroupClosed = new Emitter<EditorGroup>();
this._onGroupActivated = new Emitter<EditorGroup>();
this._onGroupDeactivated = new Emitter<EditorGroup>();
this._onGroupMoved = new Emitter<EditorGroup>();
this._onGroupRenamed = new Emitter<EditorGroup>();
this._onModelChanged = new Emitter<IStacksModelChangeEvent>();
this._onEditorDisposed = new Emitter<EditorIdentifier>();
this._onEditorDirty = new Emitter<EditorIdentifier>();
this.toDispose.push(this._onGroupOpened, this._onGroupClosed, this._onGroupActivated, this._onGroupMoved, this._onGroupRenamed, this._onModelChanged, this._onEditorDisposed, this._onEditorDirty);
this.toDispose.push(this._onGroupOpened, this._onGroupClosed, this._onGroupActivated, this._onGroupDeactivated, this._onGroupMoved, this._onGroupRenamed, this._onModelChanged, this._onEditorDisposed, this._onEditorDirty);
this.registerListeners();
}
......@@ -674,6 +676,10 @@ export class EditorStacksModel implements IEditorStacksModel {
return this._onGroupActivated.event;
}
public get onGroupDeactivated(): Event<EditorGroup> {
return this._onGroupDeactivated.event;
}
public get onGroupMoved(): Event<EditorGroup> {
return this._onGroupMoved.event;
}
......@@ -816,9 +822,13 @@ export class EditorStacksModel implements IEditorStacksModel {
return;
}
const oldActiveGroup = this._activeGroup;
this._activeGroup = group;
this.fireEvent(this._onGroupActivated, group, false);
if (oldActiveGroup) {
this.fireEvent(this._onGroupDeactivated, oldActiveGroup, false);
}
}
public moveGroup(group: EditorGroup, toIndex: number): void {
......
......@@ -41,7 +41,7 @@ if (platform.isWindows || platform.isLinux) {
const configurationRegistry = <IConfigurationRegistry>Registry.as(ConfigurationExtensions.Configuration);
configurationRegistry.registerConfiguration({
'id': 'window',
'order': 6,
'order': 8,
'title': nls.localize('windowConfigurationTitle', "Window configuration"),
'type': 'object',
'properties': {
......@@ -72,7 +72,7 @@ configurationRegistry.registerConfiguration({
// Configuration: Update
configurationRegistry.registerConfiguration({
'id': 'update',
'order': 10,
'order': 15,
'title': nls.localize('updateConfigurationTitle', "Update configuration"),
'type': 'object',
'properties': {
......
......@@ -38,7 +38,7 @@ KeybindingsRegistry.registerCommandRule({
const configurationRegistry = <IConfigurationRegistry>Registry.as(ConfigurationExtensions.Configuration);
configurationRegistry.registerConfiguration({
'id': 'emmet',
'order': 7,
'order': 6,
'title': nls.localize('emmetConfigurationTitle', "Emmet configuration"),
'type': 'object',
'properties': {
......
......@@ -161,7 +161,7 @@ let configurationRegistry = <IConfigurationRegistry>Registry.as(ConfigurationExt
configurationRegistry.registerConfiguration({
'id': 'files',
'order': 7,
'order': 9,
'title': nls.localize('filesConfigurationTitle', "Files configuration"),
'type': 'object',
'properties': {
......@@ -234,7 +234,7 @@ configurationRegistry.registerConfiguration({
configurationRegistry.registerConfiguration({
'id': 'explorer',
'order': 8,
'order': 10,
'title': nls.localize('explorerConfigurationTitle', "File Explorer configuration"),
'type': 'object',
'properties': {
......
......@@ -31,7 +31,7 @@ import {keybindingForAction, SaveFileAction, RevertFileAction, SaveFileAsAction,
import {CopyPathAction, RevealInOSAction} from 'vs/workbench/parts/files/electron-browser/electronFileActions';
import {OpenConsoleAction} from 'vs/workbench/parts/execution/electron-browser/terminal.contribution';
import {IUntitledEditorService} from 'vs/workbench/services/untitled/common/untitledEditorService';
import {CloseOtherEditorsInGroupAction, CloseEditorAction, CloseAllEditorsInGroupAction} from 'vs/workbench/browser/parts/editor/editorActions';
import {CloseOtherEditorsInGroupAction, CloseEditorAction, CloseEditorsInGroupAction} from 'vs/workbench/browser/parts/editor/editorActions';
const $ = dom.emmet;
......@@ -388,7 +388,7 @@ export class ActionProvider implements IActionProvider {
return [
saveAllAction,
this.instantiationService.createInstance(CloseAllEditorsInGroupAction, CloseAllEditorsInGroupAction.ID, CloseAllEditorsInGroupAction.LABEL)
this.instantiationService.createInstance(CloseEditorsInGroupAction, CloseEditorsInGroupAction.ID, CloseEditorsInGroupAction.LABEL)
];
}
......@@ -406,7 +406,7 @@ export class ActionProvider implements IActionProvider {
result.push(new Separator());
}
result.push(this.instantiationService.createInstance(CloseAllEditorsInGroupAction, CloseAllEditorsInGroupAction.ID, nls.localize('closeAll', "Close All")));
result.push(this.instantiationService.createInstance(CloseEditorsInGroupAction, CloseEditorsInGroupAction.ID, nls.localize('closeAll', "Close All")));
} else {
const openEditor = <OpenEditor>element;
const resource = openEditor.getResource();
......@@ -469,7 +469,7 @@ export class ActionProvider implements IActionProvider {
const closeOtherEditorsInGroupAction = this.instantiationService.createInstance(CloseOtherEditorsInGroupAction, CloseOtherEditorsInGroupAction.ID, nls.localize('closeOthers', "Close Others"));
closeOtherEditorsInGroupAction.enabled = openEditor.editorGroup.count > 1;
result.push(closeOtherEditorsInGroupAction);
result.push(this.instantiationService.createInstance(CloseAllEditorsInGroupAction, CloseAllEditorsInGroupAction.ID, nls.localize('closeAll', "Close All")));
result.push(this.instantiationService.createInstance(CloseEditorsInGroupAction, CloseEditorsInGroupAction.ID, nls.localize('closeAll', "Close All")));
}
return TPromise.as(result);
......
......@@ -509,7 +509,7 @@ export function registerContributions(): void {
var configurationRegistry = <confregistry.IConfigurationRegistry>platform.Registry.as(confregistry.Extensions.Configuration);
configurationRegistry.registerConfiguration({
id: 'git',
order: 10,
order: 15,
title: nls.localize('gitConfigurationTitle', "Git configuration"),
type: 'object',
properties: {
......
......@@ -13,12 +13,11 @@ import errors = require('vs/base/common/errors');
import nls = require('vs/nls');
import {FileEditorInput} from 'vs/workbench/parts/files/common/files';
import {EditorInputAction} from 'vs/workbench/browser/parts/editor/baseEditor';
import {getUntitledOrFileResource} from 'vs/workbench/common/editor';
import {getUntitledOrFileResource, IEditorContext} from 'vs/workbench/common/editor';
import {MarkdownEditorInput} from 'vs/workbench/parts/markdown/common/markdownEditorInput';
import {IWorkbenchEditorService} from 'vs/workbench/services/editor/common/editorService';
import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation';
import {IMessageService, Severity} from 'vs/platform/message/common/message';
import {IEditorContext} from 'vs/workbench/browser/parts/editor/editorActions';
export class GlobalTogglePreviewMarkdownAction extends Action {
......
......@@ -166,7 +166,7 @@ registry.registerWorkbenchAction(new SyncActionDescriptor(ShowAllSymbolsAction,
const configurationRegistry = <IConfigurationRegistry>Registry.as(ConfigurationExtensions.Configuration);
configurationRegistry.registerConfiguration({
'id': 'search',
'order': 10,
'order': 13,
'title': nls.localize('searchConfigurationTitle', "Search configuration"),
'type': 'object',
'properties': {
......
......@@ -84,9 +84,9 @@ export class ContextMenuService implements IContextMenuService {
const item = new remote.MenuItem({
label: e.label,
checked: e.checked,
checked: !!e.checked,
accelerator,
enabled: e.enabled,
enabled: !!e.enabled,
click: () => {
this.runAction(e, delegate);
}
......
......@@ -145,7 +145,7 @@ export class RequestService extends BaseRequestService {
let confRegistry = <IConfigurationRegistry>platform.Registry.as(Extensions.Configuration);
confRegistry.registerConfiguration({
id: 'http',
order: 9,
order: 15,
title: nls.localize('httpConfigurationTitle', "HTTP configuration"),
type: 'object',
properties: {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册