提交 4060ca0b 编写于 作者: B Benjamin Pasero

perf - also avoid compute style in parts

上级 30650de1
......@@ -9,18 +9,21 @@ import 'vs/css!./media/part';
import { Dimension, Builder } from 'vs/base/browser/builder';
import { WorkbenchComponent } from 'vs/workbench/common/component';
export interface IPartOptions {
hasTitle?: boolean;
}
/**
* Parts are layed out in the workbench and have their own layout that arranges a title,
* content and status area to show content.
* Parts are layed out in the workbench and have their own layout that arranges an optional title
* and mandatory content area to show content.
*/
export abstract class Part extends WorkbenchComponent {
private parent: Builder;
private titleArea: Builder;
private contentArea: Builder;
private statusArea: Builder;
private partLayout: PartLayout;
constructor(id: string) {
constructor(id: string, private options: IPartOptions) {
super(id);
}
......@@ -28,15 +31,14 @@ export abstract class Part extends WorkbenchComponent {
* Note: Clients should not call this method, the workbench calls this
* method. Calling it otherwise may result in unexpected behavior.
*
* Called to create title, content and status area of the part.
* Called to create title and content area of the part.
*/
public create(parent: Builder): void {
this.parent = parent;
this.titleArea = this.createTitleArea(parent);
this.contentArea = this.createContentArea(parent);
this.statusArea = this.createStatusArea(parent);
this.partLayout = new PartLayout(this.parent, this.titleArea, this.contentArea, this.statusArea);
this.partLayout = new PartLayout(this.parent, this.options, this.titleArea, this.contentArea);
}
/**
......@@ -68,14 +70,7 @@ export abstract class Part extends WorkbenchComponent {
}
/**
* Subclasses override to provide a status area implementation.
*/
protected createStatusArea(parent: Builder): Builder {
return null;
}
/**
* Layout title, content and status area in the given dimension.
* Layout title and content area in the given dimension.
*/
public layout(dimension: Dimension): Dimension[] {
return this.partLayout.layout(dimension);
......@@ -89,99 +84,32 @@ export abstract class Part extends WorkbenchComponent {
}
}
export class EmptyPart extends Part {
constructor(id: string) {
super(id);
}
}
interface IContainerStyle {
borderLeftWidth: number;
borderRightWidth: number;
borderTopWidth: number;
borderBottomWidth: number;
}
interface ITitleStatusStyle {
display: string;
height: number;
}
const TITLE_HEIGHT = 35;
export class PartLayout {
private container: Builder;
private titleArea: Builder;
private contentArea: Builder;
private statusArea: Builder;
private titleStyle: ITitleStatusStyle;
private containerStyle: IContainerStyle;
private statusStyle: ITitleStatusStyle;
constructor(container: Builder, titleArea: Builder, contentArea: Builder, statusArea: Builder) {
this.container = container;
this.titleArea = titleArea;
this.contentArea = contentArea;
this.statusArea = statusArea;
}
public computeStyle(): void {
this.containerStyle = {
borderLeftWidth: 0,
borderRightWidth: 0,
borderTopWidth: 0,
borderBottomWidth: 0
};
if (this.titleArea) {
const titleStyle = this.titleArea.getComputedStyle();
this.titleStyle = {
display: titleStyle.getPropertyValue('display'),
height: this.titleArea.getTotalSize().height
};
}
if (this.statusArea) {
const statusStyle = this.statusArea.getComputedStyle();
this.statusStyle = {
display: statusStyle.getPropertyValue('display'),
height: this.statusArea.getTotalSize().height
};
}
constructor(private container: Builder, private options: IPartOptions, private titleArea: Builder, private contentArea: Builder) {
}
public layout(dimension: Dimension): Dimension[] {
if (!this.containerStyle) {
this.computeStyle();
}
const width = dimension.width - (this.containerStyle.borderLeftWidth + this.containerStyle.borderRightWidth);
const height = dimension.height - (this.containerStyle.borderTopWidth + this.containerStyle.borderBottomWidth);
const {width, height} = dimension;
// Return the applied sizes to title, content and status
// Return the applied sizes to title and content
const sizes: Dimension[] = [];
// Title Size: Width (Fill), Height (Variable)
let titleSize: Dimension;
if (this.titleArea && this.titleStyle.display !== 'none') {
titleSize = new Dimension(width, Math.min(height, this.titleStyle.height));
if (this.options && this.options.hasTitle) {
titleSize = new Dimension(width, Math.min(height, TITLE_HEIGHT));
} else {
titleSize = new Dimension(0, 0);
}
// Status Size: Width (Fill), Height (Variable)
let statusSize: Dimension;
if (this.statusArea && this.statusStyle.display !== 'none') {
this.statusArea.getHTMLElement().style.height = this.statusArea.getHTMLElement().style.width = '';
statusSize = new Dimension(width, Math.min(height - titleSize.height, this.statusStyle.height));
} else {
statusSize = new Dimension(0, 0);
}
// Content Size: Width (Fill), Height (Variable)
const contentSize = new Dimension(width, height - titleSize.height - statusSize.height);
const contentSize = new Dimension(width, height - titleSize.height);
sizes.push(titleSize);
sizes.push(contentSize);
sizes.push(statusSize);
// Content
if (this.contentArea) {
......
......@@ -64,7 +64,7 @@ export class ActivitybarPart extends Part implements IActivityBarService {
@IInstantiationService private instantiationService: IInstantiationService,
@IPartService private partService: IPartService
) {
super(id);
super(id, { hasTitle: false });
this.viewletIdToActionItems = Object.create(null);
this.viewletIdToActions = Object.create(null);
......
......@@ -20,7 +20,7 @@ import { IActionItem, ActionsOrientation } from 'vs/base/browser/ui/actionbar/ac
import { ProgressBar } from 'vs/base/browser/ui/progressbar/progressbar';
import { IActionBarRegistry, Extensions, prepareActions } from 'vs/workbench/browser/actionBarRegistry';
import { Action, IAction } from 'vs/base/common/actions';
import { Part } from 'vs/workbench/browser/part';
import { Part, IPartOptions } from 'vs/workbench/browser/part';
import { Composite, CompositeRegistry } from 'vs/workbench/browser/composite';
import { IComposite } from 'vs/workbench/common/composite';
import { WorkbenchProgressService } from 'vs/workbench/services/progress/browser/progressService';
......@@ -65,9 +65,10 @@ export abstract class CompositePart<T extends Composite> extends Part {
private nameForTelemetry: string,
private compositeCSSClass: string,
private actionContributionScope: string,
id: string
id: string,
options: IPartOptions
) {
super(id);
super(id, options);
this.instantiatedCompositeListeners = [];
this.mapCompositeToCompositeContainer = {};
......
......@@ -115,7 +115,7 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService
@IContextKeyService contextKeyService: IContextKeyService,
@IInstantiationService private instantiationService: IInstantiationService
) {
super(id);
super(id, { hasTitle: false });
this._onEditorsChanged = new Emitter<void>();
this._onEditorsMoved = new Emitter<void>();
......
......@@ -58,7 +58,8 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
'panel',
'panel',
Scope.PANEL,
id
id,
{ hasTitle: true }
);
}
......
......@@ -65,7 +65,8 @@ export class SidebarPart extends CompositePart<Viewlet> implements ISidebar {
'sideBar',
'viewlet',
Scope.VIEWLET,
id
id,
{ hasTitle: true }
);
}
......
......@@ -42,7 +42,7 @@ export class StatusbarPart extends Part implements IStatusbarService {
id: string,
@IInstantiationService private instantiationService: IInstantiationService
) {
super(id);
super(id, { hasTitle: false });
this.toDispose = [];
}
......
......@@ -35,7 +35,7 @@ export class TitlebarPart extends Part implements ITitleService {
@IWindowService private windowService: IWindowService,
@IWindowsService private windowsService: IWindowsService
) {
super(id);
super(id, { hasTitle: false });
this.registerListeners();
}
......
......@@ -17,7 +17,7 @@ import { TestWorkspace } from 'vs/platform/workspace/test/common/testWorkspace';
class MyPart extends Part {
constructor(private expectedParent: Builder) {
super('myPart');
super('myPart', { hasTitle: true });
}
public createTitleArea(parent: Builder): Builder {
......@@ -30,11 +30,6 @@ class MyPart extends Part {
return super.createContentArea(parent);
}
public createStatusArea(parent: Builder): Builder {
assert.strictEqual(parent, this.expectedParent);
return super.createStatusArea(parent);
}
public getMemento(storageService: IStorageService): any {
return super.getMemento(storageService);
}
......@@ -43,7 +38,7 @@ class MyPart extends Part {
class MyPart2 extends Part {
constructor() {
super('myPart2');
super('myPart2', { hasTitle: true });
}
public createTitleArea(parent: Builder): Builder {
......@@ -63,21 +58,12 @@ class MyPart2 extends Part {
});
});
}
public createStatusArea(parent: Builder): Builder {
return parent.div(function (div) {
div.span({
id: 'myPart.status',
innerHtml: 'Status'
});
});
}
}
class MyPart3 extends Part {
constructor() {
super('myPart2');
super('myPart2', { hasTitle: false });
}
public createTitleArea(parent: Builder): Builder {
......@@ -92,10 +78,6 @@ class MyPart3 extends Part {
});
});
}
public createStatusArea(parent: Builder): Builder {
return null;
}
}
suite('Workbench Part', () => {
......@@ -153,7 +135,7 @@ suite('Workbench Part', () => {
assert.strictEqual(Types.isEmptyObject(memento), true);
});
test('Part Layout with Title, Content and Status', function () {
test('Part Layout with Title and Content', function () {
let b = Build.withElementById(fixtureId);
b.div().hide();
......@@ -162,7 +144,6 @@ suite('Workbench Part', () => {
assert(Build.withElementById('myPart.title'));
assert(Build.withElementById('myPart.content'));
assert(Build.withElementById('myPart.status'));
});
test('Part Layout with Content only', function () {
......@@ -174,6 +155,5 @@ suite('Workbench Part', () => {
assert(!Build.withElementById('myPart.title'));
assert(Build.withElementById('myPart.content'));
assert(!Build.withElementById('myPart.status'));
});
});
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册