Files
vscode/src/vs/workbench/browser/part.ts
2016-04-28 08:13:07 +02:00

208 lines
5.7 KiB
TypeScript

/*---------------------------------------------------------------------------------------------
* 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/part';
import {Dimension, Builder} from 'vs/base/browser/builder';
import {WorkbenchComponent} from 'vs/workbench/common/component';
/**
* Parts are layed out in the workbench and have their own layout that arranges a title,
* content and status 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) {
super(id);
}
/**
* 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.
*/
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);
}
/**
* Returns the overall part container.
*/
public getContainer(): Builder {
return this.parent;
}
/**
* Subclasses override to provide a title area implementation.
*/
public createTitleArea(parent: Builder): Builder {
return null;
}
/**
* Returns the title area container.
*/
public getTitleArea(): Builder {
return this.titleArea;
}
/**
* Subclasses override to provide a content area implementation.
*/
public createContentArea(parent: Builder): Builder {
return null;
}
/**
* Returns the content area container.
*/
public getContentArea(): Builder {
return this.contentArea;
}
/**
* Subclasses override to provide a status area implementation.
*/
public createStatusArea(parent: Builder): Builder {
return null;
}
/**
* Returns the status area container.
*/
public getStatusArea(): Builder {
return this.statusArea;
}
/**
* Layout title, content and status area in the given dimension.
*/
public layout(dimension: Dimension): Dimension[] {
return this.partLayout.layout(dimension);
}
/**
* Returns the part layout implementation.
*/
public getLayout(): PartLayout {
return this.partLayout;
}
}
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;
}
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 {
let containerStyle = this.container.getComputedStyle();
this.containerStyle = {
borderLeftWidth: parseInt(containerStyle.getPropertyValue('border-left-width'), 10),
borderRightWidth: parseInt(containerStyle.getPropertyValue('border-right-width'), 10),
borderTopWidth: parseInt(containerStyle.getPropertyValue('border-top-width'), 10),
borderBottomWidth: parseInt(containerStyle.getPropertyValue('border-bottom-width'), 10)
};
if (this.titleArea) {
let titleStyle = this.titleArea.getComputedStyle();
this.titleStyle = {
display: titleStyle.getPropertyValue('display'),
height: this.titleArea.getTotalSize().height
};
}
if (this.statusArea) {
let statusStyle = this.statusArea.getComputedStyle();
this.statusStyle = {
display: statusStyle.getPropertyValue('display'),
height: this.statusArea.getTotalSize().height
};
}
}
public layout(dimension: Dimension): Dimension[] {
if (!this.containerStyle) {
this.computeStyle();
}
let width = dimension.width - (this.containerStyle.borderLeftWidth + this.containerStyle.borderRightWidth);
let height = dimension.height - (this.containerStyle.borderTopWidth + this.containerStyle.borderBottomWidth);
// Return the applied sizes to title, content and status
let 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));
} 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)
let contentSize = new Dimension(width, height - titleSize.height - statusSize.height);
sizes.push(titleSize);
sizes.push(contentSize);
sizes.push(statusSize);
// Content
if (this.contentArea) {
this.contentArea.size(contentSize.width, contentSize.height);
}
return sizes;
}
}