mirror of
https://github.com/Microsoft/vscode
synced 2024-08-27 21:09:43 +00:00
grid example
This commit is contained in:
parent
2866ee1ae8
commit
673355d8f4
149
src/vs/base/browser/ui/splitview/grid.ts
Normal file
149
src/vs/base/browser/ui/splitview/grid.ts
Normal file
|
@ -0,0 +1,149 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 Event, { anyEvent } from 'vs/base/common/event';
|
||||
import { Orientation } from 'vs/base/browser/ui/sash/sash';
|
||||
import { append, $ } from 'vs/base/browser/dom';
|
||||
import { SplitView, IView } from 'vs/base/browser/ui/splitview/splitview';
|
||||
export { Orientation } from 'vs/base/browser/ui/sash/sash';
|
||||
|
||||
export class GridNode implements IView {
|
||||
|
||||
get minimumSize(): number {
|
||||
let result = 0;
|
||||
|
||||
for (const child of this.children) {
|
||||
for (const grandchild of child.children) {
|
||||
result += grandchild.minimumSize;
|
||||
}
|
||||
}
|
||||
|
||||
return result === 0 ? 50 : result;
|
||||
}
|
||||
|
||||
readonly maximumSize = Number.MAX_VALUE;
|
||||
|
||||
private _onDidChange: Event<number | undefined> = Event.None;
|
||||
get onDidChange(): Event<number | undefined> {
|
||||
return this._onDidChange;
|
||||
}
|
||||
|
||||
protected orientation: Orientation | undefined;
|
||||
protected size: number | undefined;
|
||||
protected orthogonalSize: number | undefined;
|
||||
private splitview: SplitView | undefined;
|
||||
private children: GridNode[] = [];
|
||||
private color: string | undefined;
|
||||
|
||||
constructor(private parent?: GridNode, orthogonalSize?: number, color?: string) {
|
||||
this.orthogonalSize = orthogonalSize;
|
||||
this.color = color || `hsl(${Math.round(Math.random() * 360)}, 72%, 72%)`;
|
||||
}
|
||||
|
||||
render(container: HTMLElement): void {
|
||||
container = append(container, $('.node'));
|
||||
container.style.backgroundColor = this.color;
|
||||
|
||||
append(container, $('.action', { onclick: () => this.split(container, Orientation.HORIZONTAL) }, '⬌'));
|
||||
append(container, $('.action', { onclick: () => this.split(container, Orientation.VERTICAL) }, '⬍'));
|
||||
}
|
||||
|
||||
protected split(container: HTMLElement, orientation: Orientation): void {
|
||||
if (this.parent && this.parent.orientation === orientation) {
|
||||
const index = this.parent.children.indexOf(this);
|
||||
this.parent.addChild(this.size / 2, this.orthogonalSize, index + 1);
|
||||
} else {
|
||||
this.branch(container, orientation);
|
||||
}
|
||||
}
|
||||
|
||||
protected branch(container: HTMLElement, orientation: Orientation): void {
|
||||
this.orientation = orientation;
|
||||
container.innerHTML = '';
|
||||
|
||||
this.splitview = new SplitView(container, { orientation });
|
||||
this.layout(this.size);
|
||||
this.orthogonalLayout(this.orthogonalSize);
|
||||
|
||||
this.addChild(this.orthogonalSize / 2, this.size, 0, this.color);
|
||||
this.addChild(this.orthogonalSize / 2, this.size);
|
||||
}
|
||||
|
||||
layout(size: number): void {
|
||||
this.size = size;
|
||||
|
||||
for (const child of this.children) {
|
||||
child.orthogonalLayout(size);
|
||||
}
|
||||
}
|
||||
|
||||
orthogonalLayout(size: number): void {
|
||||
this.orthogonalSize = size;
|
||||
|
||||
if (this.splitview) {
|
||||
this.splitview.layout(size);
|
||||
}
|
||||
}
|
||||
|
||||
private addChild(size: number, orthogonalSize: number, index?: number, color?: string): void {
|
||||
const child = new GridNode(this, orthogonalSize, color);
|
||||
this.splitview.addView(child, size, index);
|
||||
|
||||
if (typeof index === 'number') {
|
||||
this.children.splice(index, 0, child);
|
||||
} else {
|
||||
this.children.push(child);
|
||||
}
|
||||
|
||||
this._onDidChange = anyEvent(...this.children.map(c => c.onDidChange));
|
||||
}
|
||||
}
|
||||
|
||||
export class RootGridNode extends GridNode {
|
||||
|
||||
private width: number;
|
||||
private height: number;
|
||||
|
||||
protected branch(container: HTMLElement, orientation: Orientation): void {
|
||||
if (orientation === Orientation.VERTICAL) {
|
||||
this.size = this.width;
|
||||
this.orthogonalSize = this.height;
|
||||
} else {
|
||||
this.size = this.height;
|
||||
this.orthogonalSize = this.width;
|
||||
}
|
||||
|
||||
super.branch(container, orientation);
|
||||
}
|
||||
|
||||
layoutBox(width: number, height: number): void {
|
||||
if (this.orientation === Orientation.VERTICAL) {
|
||||
this.layout(width);
|
||||
this.orthogonalLayout(height);
|
||||
} else if (this.orientation === Orientation.HORIZONTAL) {
|
||||
this.layout(height);
|
||||
this.orthogonalLayout(width);
|
||||
} else {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class Grid {
|
||||
|
||||
private root: RootGridNode;
|
||||
|
||||
constructor(container: HTMLElement) {
|
||||
this.root = new RootGridNode();
|
||||
this.root.render(container);
|
||||
}
|
||||
|
||||
layout(width: number, height: number): void {
|
||||
this.root.layoutBox(width, height);
|
||||
}
|
||||
}
|
59
test/grid.html
Normal file
59
test/grid.html
Normal file
|
@ -0,0 +1,59 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>Grid Example</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<script src="../out/vs/loader.js"></script>
|
||||
<script>
|
||||
require.config({ baseUrl: '../out' });
|
||||
|
||||
require(['vs/base/browser/ui/splitview/grid'], ({ Grid }) => {
|
||||
const grid = new Grid(document.body);
|
||||
const layout = () => grid.layout(document.body.clientWidth, document.body.clientHeight);
|
||||
window.onresize = layout;
|
||||
layout();
|
||||
});
|
||||
</script>
|
||||
<style>
|
||||
html,
|
||||
body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.node {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.action {
|
||||
display: inline-block;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border: 1px solid #3c3c3c;
|
||||
text-align: center;
|
||||
line-height: 16px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.action:hover {
|
||||
cursor: pointer;
|
||||
background-color: #ffffff54;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
Loading…
Reference in a new issue