提交 619c7e86 编写于 作者: B Benjamin Pasero

grid - first cut empty editor groups

上级 c569505a
...@@ -7,6 +7,12 @@ ...@@ -7,6 +7,12 @@
height: 100%; height: 100%;
} }
.monaco-workbench > .part.editor > .content .editor-group-container.empty.active {
outline-width: 1px;
outline-style: solid;
outline-offset: -2px;
}
.monaco-workbench > .part.editor > .content .editor-group-container > .title { .monaco-workbench > .part.editor > .content .editor-group-container > .title {
height: 35px; height: 35px;
display: flex; display: flex;
...@@ -16,4 +22,9 @@ ...@@ -16,4 +22,9 @@
.monaco-workbench > .part.editor > .content .editor-group-container > .editor-container { .monaco-workbench > .part.editor > .content .editor-group-container > .editor-container {
height: calc(100% - 35px); /* below title control */ height: calc(100% - 35px); /* below title control */
}
.monaco-workbench > .part.editor > .content .editor-group-container.empty > .title,
.monaco-workbench > .part.editor > .content .editor-group-container.empty > .editor-container {
display: none;
} }
\ No newline at end of file
...@@ -54,7 +54,7 @@ ...@@ -54,7 +54,7 @@
display: none; display: none;
} }
/* Drag Cursor */ /* Drag Cursor (TODO@grid this depends on the feature to drag an entire group to another location) */
.monaco-workbench > .part.editor > .content.multiple-groups .editor-group-container > .title, .monaco-workbench > .part.editor > .content.multiple-groups .editor-group-container > .title,
.monaco-workbench > .part.editor > .content.multiple-groups .editor-group-container > .title.tabs .scrollbar .slider, .monaco-workbench > .part.editor > .content.multiple-groups .editor-group-container > .title.tabs .scrollbar .slider,
.monaco-workbench > .part.editor > .content.multiple-groups .editor-group-container > .title .monaco-icon-label::before, .monaco-workbench > .part.editor > .content.multiple-groups .editor-group-container > .title .monaco-icon-label::before,
......
...@@ -10,14 +10,14 @@ import { EditorGroup } from 'vs/workbench/common/editor/editorStacksModel'; ...@@ -10,14 +10,14 @@ import { EditorGroup } from 'vs/workbench/common/editor/editorStacksModel';
import { EditorInput, EditorOptions, GroupIdentifier } from 'vs/workbench/common/editor'; import { EditorInput, EditorOptions, GroupIdentifier } from 'vs/workbench/common/editor';
import { Event, Emitter } from 'vs/base/common/event'; import { Event, Emitter } from 'vs/base/common/event';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { addClass, addClasses, Dimension, trackFocus, toggleClass } from 'vs/base/browser/dom'; import { addClass, addClasses, Dimension, trackFocus, toggleClass, removeClass } from 'vs/base/browser/dom';
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { ProgressBar } from 'vs/base/browser/ui/progressbar/progressbar'; import { ProgressBar } from 'vs/base/browser/ui/progressbar/progressbar';
import { attachProgressBarStyler } from 'vs/platform/theme/common/styler'; import { attachProgressBarStyler } from 'vs/platform/theme/common/styler';
import { IThemeService } from 'vs/platform/theme/common/themeService'; import { IThemeService } from 'vs/platform/theme/common/themeService';
import { editorBackground, contrastBorder } from 'vs/platform/theme/common/colorRegistry'; import { editorBackground, contrastBorder, focusBorder } from 'vs/platform/theme/common/colorRegistry';
import { Themable, EDITOR_GROUP_HEADER_TABS_BORDER, EDITOR_GROUP_HEADER_TABS_BACKGROUND } from 'vs/workbench/common/theme'; import { Themable, EDITOR_GROUP_HEADER_TABS_BORDER, EDITOR_GROUP_HEADER_TABS_BACKGROUND, EDITOR_GROUP_BACKGROUND } from 'vs/workbench/common/theme';
import { IOpenEditorResult, INextEditorGroup } from 'vs/workbench/services/editor/common/nextEditorGroupsService'; import { IOpenEditorResult, INextEditorGroup } from 'vs/workbench/services/editor/common/nextEditorGroupsService';
import { INextTitleAreaControl } from 'vs/workbench/browser/parts/editor2/nextTitleControl'; import { INextTitleAreaControl } from 'vs/workbench/browser/parts/editor2/nextTitleControl';
import { NextTabsTitleControl } from 'vs/workbench/browser/parts/editor2/nextTabsTitleControl'; import { NextTabsTitleControl } from 'vs/workbench/browser/parts/editor2/nextTabsTitleControl';
...@@ -26,14 +26,20 @@ import { IView } from 'vs/base/browser/ui/grid/gridview'; ...@@ -26,14 +26,20 @@ import { IView } from 'vs/base/browser/ui/grid/gridview';
import { IProgressService } from 'vs/platform/progress/common/progress'; import { IProgressService } from 'vs/platform/progress/common/progress';
import { ProgressService } from 'vs/workbench/services/progress/browser/progressService'; import { ProgressService } from 'vs/workbench/services/progress/browser/progressService';
import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor';
import { localize } from 'vs/nls';
export class NextEditorGroupView extends Themable implements IView, INextEditorGroup { export class NextEditorGroupView extends Themable implements IView, INextEditorGroup {
private static readonly EDITOR_TITLE_HEIGHT = 35; private static readonly EDITOR_TITLE_HEIGHT = 35;
private _onDidFocus: Emitter<void> = this._register(new Emitter<void>()); private _onDidFocus: Emitter<void> = this._register(new Emitter<void>());
get onDidFocus(): Event<void> { return this._onDidFocus.event; }
private _onWillDispose: Emitter<void> = this._register(new Emitter<void>()); private _onWillDispose: Emitter<void> = this._register(new Emitter<void>());
get onWillDispose(): Event<void> { return this._onWillDispose.event; }
private _onDidActiveEditorChange: Emitter<BaseEditor> = this._register(new Emitter<BaseEditor>()); private _onDidActiveEditorChange: Emitter<BaseEditor> = this._register(new Emitter<BaseEditor>());
get onDidActiveEditorChange(): Event<BaseEditor> { return this._onDidActiveEditorChange.event; }
private group: EditorGroup; private group: EditorGroup;
private dimension: Dimension; private dimension: Dimension;
...@@ -57,17 +63,62 @@ export class NextEditorGroupView extends Themable implements IView, INextEditorG ...@@ -57,17 +63,62 @@ export class NextEditorGroupView extends Themable implements IView, INextEditorG
this.group = this._register(instantiationService.createInstance(EditorGroup, '')); this.group = this._register(instantiationService.createInstance(EditorGroup, ''));
this.group.label = `Group <${this.group.id}>`; this.group.label = `Group <${this.group.id}>`;
this.element = document.createElement('div'); this.doCreate();
addClass(this.element, 'editor-group-container'); this.registerListeners();
this.doRender(); }
private registerListeners(): void {
this._register(this.group.onEditorsStructureChanged(() => this.updateContainer()));
} }
get onDidFocus(): Event<void> { private doCreate(): void {
return this._onDidFocus.event;
// Container
addClasses(this.element, 'editor-group-container');
const focusTracker = this._register(trackFocus(this.element));
this._register(focusTracker.onDidFocus(() => {
this._onDidFocus.fire();
}));
// Title container
this.titleContainer = document.createElement('div');
addClasses(this.titleContainer, 'title', 'tabs', 'show-file-icons');
this.element.appendChild(this.titleContainer);
// Progress bar
this.progressBar = this._register(new ProgressBar(this.element));
this._register(attachProgressBarStyler(this.progressBar, this.themeService));
this.progressBar.hide();
// Editor container
this.editorContainer = document.createElement('div');
addClass(this.editorContainer, 'editor-container');
this.element.appendChild(this.editorContainer);
// Update styles
this.updateStyles();
// Update containers
this.updateContainer();
} }
get onWillDispose(): Event<void> { private updateContainer(): void {
return this._onWillDispose.event; const empty = this.group.count === 0;
// Empty Container: allow to focus
if (empty) {
addClass(this.element, 'empty');
this.element.tabIndex = 0;
this.element.setAttribute('aria-label', localize('emptyEditorGroup', "Empty Editor Group"));
}
// Non-Empty Container: revert empty container attributes
else {
removeClass(this.element, 'empty');
this.element.removeAttribute('tabIndex');
this.element.removeAttribute('aria-label');
}
} }
setActive(isActive: boolean): void { setActive(isActive: boolean): void {
...@@ -84,10 +135,6 @@ export class NextEditorGroupView extends Themable implements IView, INextEditorG ...@@ -84,10 +135,6 @@ export class NextEditorGroupView extends Themable implements IView, INextEditorG
//#region INextEditorGroup Implementation //#region INextEditorGroup Implementation
get onDidActiveEditorChange(): Event<BaseEditor> {
return this._onDidActiveEditorChange.event;
}
get id(): GroupIdentifier { get id(): GroupIdentifier {
return this.group.id; return this.group.id;
} }
...@@ -175,7 +222,10 @@ export class NextEditorGroupView extends Themable implements IView, INextEditorG ...@@ -175,7 +222,10 @@ export class NextEditorGroupView extends Themable implements IView, INextEditorG
//#region Themable Implementation //#region Themable Implementation
protected updateStyles(): void { protected updateStyles(): void {
super.updateStyles();
// Container
this.element.style.backgroundColor = this.getColor(EDITOR_GROUP_BACKGROUND);
this.element.style.outlineColor = this.getColor(focusBorder);
// Title control // Title control
const borderColor = this.getColor(EDITOR_GROUP_HEADER_TABS_BORDER) || this.getColor(contrastBorder); const borderColor = this.getColor(EDITOR_GROUP_HEADER_TABS_BORDER) || this.getColor(contrastBorder);
...@@ -184,17 +234,15 @@ export class NextEditorGroupView extends Themable implements IView, INextEditorG ...@@ -184,17 +234,15 @@ export class NextEditorGroupView extends Themable implements IView, INextEditorG
this.titleContainer.style.borderBottomStyle = borderColor ? 'solid' : null; this.titleContainer.style.borderBottomStyle = borderColor ? 'solid' : null;
this.titleContainer.style.borderBottomColor = borderColor; this.titleContainer.style.borderBottomColor = borderColor;
// Editor background // Editor container
this.element.style.backgroundColor = this.getColor(editorBackground); this.editorContainer.style.backgroundColor = this.getColor(editorBackground);
// TODO@grid use editor group background for empty groups?
} }
//#endregion //#endregion
//#region IView implementation //#region IView implementation
readonly element: HTMLElement; readonly element: HTMLElement = document.createElement('div');
readonly minimumWidth = 170; readonly minimumWidth = 170;
readonly minimumHeight = 70; readonly minimumHeight = 70;
...@@ -203,34 +251,6 @@ export class NextEditorGroupView extends Themable implements IView, INextEditorG ...@@ -203,34 +251,6 @@ export class NextEditorGroupView extends Themable implements IView, INextEditorG
get onDidChange() { return Event.None; } get onDidChange() { return Event.None; }
private doRender(): void {
// Title container
this.titleContainer = document.createElement('div');
addClasses(this.titleContainer, 'title', 'tabs', 'show-file-icons', 'active');
this.element.appendChild(this.titleContainer);
// Progress bar
this.progressBar = this._register(new ProgressBar(this.element));
this._register(attachProgressBarStyler(this.progressBar, this.themeService));
this.progressBar.hide();
// Editor container
this.editorContainer = document.createElement('div');
addClass(this.editorContainer, 'editor-container');
this.editorContainer.setAttribute('role', 'tabpanel');
this.element.appendChild(this.editorContainer);
// Track focus in editor container
const focusTracker = this._register(trackFocus(this.editorContainer));
this._register(focusTracker.onDidFocus(() => {
this._onDidFocus.fire();
}));
// Update styles
this.updateStyles();
}
layout(width: number, height: number): void { layout(width: number, height: number): void {
this.dimension = new Dimension(width, height); this.dimension = new Dimension(width, height);
...@@ -251,6 +271,8 @@ export class NextEditorGroupView extends Themable implements IView, INextEditorG ...@@ -251,6 +271,8 @@ export class NextEditorGroupView extends Themable implements IView, INextEditorG
} }
} }
//#endregion
shutdown(): void { shutdown(): void {
if (this.editorControl) { if (this.editorControl) {
this.editorControl.shutdown(); this.editorControl.shutdown();
...@@ -262,6 +284,4 @@ export class NextEditorGroupView extends Themable implements IView, INextEditorG ...@@ -262,6 +284,4 @@ export class NextEditorGroupView extends Themable implements IView, INextEditorG
super.dispose(); super.dispose();
} }
//#endregion
} }
\ No newline at end of file
...@@ -25,7 +25,10 @@ export class NextEditorPart extends Part implements INextEditorGroupsService { ...@@ -25,7 +25,10 @@ export class NextEditorPart extends Part implements INextEditorGroupsService {
_serviceBrand: any; _serviceBrand: any;
private _onDidLayout: Emitter<Dimension> = this._register(new Emitter<Dimension>()); private _onDidLayout: Emitter<Dimension> = this._register(new Emitter<Dimension>());
get onDidLayout(): Event<Dimension> { return this._onDidLayout.event; }
private _onDidActiveGroupChange: Emitter<NextEditorGroupView> = this._register(new Emitter<NextEditorGroupView>()); private _onDidActiveGroupChange: Emitter<NextEditorGroupView> = this._register(new Emitter<NextEditorGroupView>());
get onDidActiveGroupChange(): Event<NextEditorGroupView> { return this._onDidActiveGroupChange.event; }
private dimension: Dimension; private dimension: Dimension;
...@@ -47,10 +50,6 @@ export class NextEditorPart extends Part implements INextEditorGroupsService { ...@@ -47,10 +50,6 @@ export class NextEditorPart extends Part implements INextEditorGroupsService {
//#region INextEditorGroupsService Implementation //#region INextEditorGroupsService Implementation
get onDidActiveGroupChange(): Event<NextEditorGroupView> {
return this._onDidActiveGroupChange.event;
}
get activeGroup(): NextEditorGroupView { get activeGroup(): NextEditorGroupView {
return this._activeGroup; return this._activeGroup;
} }
...@@ -163,12 +162,7 @@ export class NextEditorPart extends Part implements INextEditorGroupsService { ...@@ -163,12 +162,7 @@ export class NextEditorPart extends Part implements INextEditorGroupsService {
//#region Part Implementation //#region Part Implementation
get onDidLayout(): Event<Dimension> {
return this._onDidLayout.event;
}
protected updateStyles(): void { protected updateStyles(): void {
super.updateStyles();
// Part container // Part container
const container = this.getContainer(); const container = this.getContainer();
......
...@@ -365,10 +365,7 @@ export abstract class NextTitleControl extends Themable implements INextTitleAre ...@@ -365,10 +365,7 @@ export abstract class NextTitleControl extends Themable implements INextTitleAre
//#region IThemeable implementation //#region IThemeable implementation
protected updateStyles(): void { protected updateStyles(): void {
super.updateStyles(); this.doScheduleUpdate(true); // run a sync update when the theme changes to new styles
// run a sync update when the theme changes to new styles
this.doScheduleUpdate(true);
} }
//#endregion //#endregion
......
...@@ -12,7 +12,7 @@ import { IStorageService, StorageScope } from 'vs/platform/storage/common/storag ...@@ -12,7 +12,7 @@ import { IStorageService, StorageScope } from 'vs/platform/storage/common/storag
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IConfigurationService, IConfigurationChangeEvent } from 'vs/platform/configuration/common/configuration'; import { IConfigurationService, IConfigurationChangeEvent } from 'vs/platform/configuration/common/configuration';
import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle';
import { dispose, IDisposable } from 'vs/base/common/lifecycle'; import { dispose, IDisposable, Disposable } from 'vs/base/common/lifecycle';
import { Registry } from 'vs/platform/registry/common/platform'; import { Registry } from 'vs/platform/registry/common/platform';
import { Position, Direction } from 'vs/platform/editor/common/editor'; import { Position, Direction } from 'vs/platform/editor/common/editor';
import { ResourceMap } from 'vs/base/common/map'; import { ResourceMap } from 'vs/base/common/map';
...@@ -44,23 +44,10 @@ export interface ISerializedEditorGroup { ...@@ -44,23 +44,10 @@ export interface ISerializedEditorGroup {
preview: number; preview: number;
} }
export class EditorGroup implements IEditorGroup { export class EditorGroup extends Disposable implements IEditorGroup {
private static IDS = 0; private static IDS = 0;
private _id: GroupIdentifier;
private _label: string;
private editors: EditorInput[];
private mru: EditorInput[];
private mapResourceToEditorCount: ResourceMap<number>;
private preview: EditorInput; // editor in preview state
private active: EditorInput; // editor in active state
private toDispose: IDisposable[];
private editorOpenPositioning: 'left' | 'right' | 'first' | 'last';
private readonly _onEditorActivated: Emitter<EditorInput>; private readonly _onEditorActivated: Emitter<EditorInput>;
private readonly _onEditorOpened: Emitter<EditorInput>; private readonly _onEditorOpened: Emitter<EditorInput>;
private readonly _onEditorClosed: Emitter<EditorCloseEvent>; private readonly _onEditorClosed: Emitter<EditorCloseEvent>;
...@@ -73,32 +60,43 @@ export class EditorGroup implements IEditorGroup { ...@@ -73,32 +60,43 @@ export class EditorGroup implements IEditorGroup {
private readonly _onEditorStateChanged: Emitter<EditorInput>; private readonly _onEditorStateChanged: Emitter<EditorInput>;
private readonly _onEditorsStructureChanged: Emitter<EditorInput>; private readonly _onEditorsStructureChanged: Emitter<EditorInput>;
private _id: GroupIdentifier;
private _label: string;
private editors: EditorInput[];
private mru: EditorInput[];
private mapResourceToEditorCount: ResourceMap<number>;
private preview: EditorInput; // editor in preview state
private active: EditorInput; // editor in active state
private editorOpenPositioning: 'left' | 'right' | 'first' | 'last';
constructor( constructor(
arg1: string | ISerializedEditorGroup, arg1: string | ISerializedEditorGroup,
@IInstantiationService private instantiationService: IInstantiationService, @IInstantiationService private instantiationService: IInstantiationService,
@IConfigurationService private configurationService: IConfigurationService @IConfigurationService private configurationService: IConfigurationService
) { ) {
super();
this._id = EditorGroup.IDS++; this._id = EditorGroup.IDS++;
this.editors = []; this.editors = [];
this.mru = []; this.mru = [];
this.toDispose = [];
this.mapResourceToEditorCount = new ResourceMap<number>(); this.mapResourceToEditorCount = new ResourceMap<number>();
this.onConfigurationUpdated(); this.onConfigurationUpdated();
this._onEditorActivated = new Emitter<EditorInput>(); this._onEditorActivated = this._register(new Emitter<EditorInput>());
this._onEditorOpened = new Emitter<EditorInput>(); this._onEditorOpened = this._register(new Emitter<EditorInput>());
this._onEditorClosed = new Emitter<EditorCloseEvent>(); this._onEditorClosed = this._register(new Emitter<EditorCloseEvent>());
this._onEditorDisposed = new Emitter<EditorInput>(); this._onEditorDisposed = this._register(new Emitter<EditorInput>());
this._onEditorDirty = new Emitter<EditorInput>(); this._onEditorDirty = this._register(new Emitter<EditorInput>());
this._onEditorLabelChange = new Emitter<EditorInput>(); this._onEditorLabelChange = this._register(new Emitter<EditorInput>());
this._onEditorMoved = new Emitter<EditorInput>(); this._onEditorMoved = this._register(new Emitter<EditorInput>());
this._onEditorPinned = new Emitter<EditorInput>(); this._onEditorPinned = this._register(new Emitter<EditorInput>());
this._onEditorUnpinned = new Emitter<EditorInput>(); this._onEditorUnpinned = this._register(new Emitter<EditorInput>());
this._onEditorStateChanged = new Emitter<EditorInput>(); this._onEditorStateChanged = this._register(new Emitter<EditorInput>());
this._onEditorsStructureChanged = new Emitter<EditorInput>(); this._onEditorsStructureChanged = this._register(new Emitter<EditorInput>());
this.toDispose.push(this._onEditorActivated, this._onEditorOpened, this._onEditorClosed, this._onEditorDisposed, this._onEditorDirty, this._onEditorLabelChange, this._onEditorMoved, this._onEditorPinned, this._onEditorUnpinned, this._onEditorStateChanged, this._onEditorsStructureChanged);
if (typeof arg1 === 'object') { if (typeof arg1 === 'object') {
this.deserialize(arg1); this.deserialize(arg1);
...@@ -110,7 +108,7 @@ export class EditorGroup implements IEditorGroup { ...@@ -110,7 +108,7 @@ export class EditorGroup implements IEditorGroup {
} }
private registerListeners(): void { private registerListeners(): void {
this.toDispose.push(this.configurationService.onDidChangeConfiguration(e => this.onConfigurationUpdated(e))); this._register(this.configurationService.onDidChangeConfiguration(e => this.onConfigurationUpdated(e)));
} }
private onConfigurationUpdated(event?: IConfigurationChangeEvent): void { private onConfigurationUpdated(event?: IConfigurationChangeEvent): void {
...@@ -687,10 +685,6 @@ export class EditorGroup implements IEditorGroup { ...@@ -687,10 +685,6 @@ export class EditorGroup implements IEditorGroup {
this.active = this.mru[0]; this.active = this.mru[0];
this.preview = this.editors[data.preview]; this.preview = this.editors[data.preview];
} }
public dispose(): void {
dispose(this.toDispose);
}
} }
interface ISerializedEditorStacksModel { interface ISerializedEditorStacksModel {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册