Skip to content

Commit 673355d

Browse files
committed
grid example
1 parent 2866ee1 commit 673355d

File tree

2 files changed

+208
-0
lines changed

2 files changed

+208
-0
lines changed
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
'use strict';
7+
8+
import Event, { anyEvent } from 'vs/base/common/event';
9+
import { Orientation } from 'vs/base/browser/ui/sash/sash';
10+
import { append, $ } from 'vs/base/browser/dom';
11+
import { SplitView, IView } from 'vs/base/browser/ui/splitview/splitview';
12+
export { Orientation } from 'vs/base/browser/ui/sash/sash';
13+
14+
export class GridNode implements IView {
15+
16+
get minimumSize(): number {
17+
let result = 0;
18+
19+
for (const child of this.children) {
20+
for (const grandchild of child.children) {
21+
result += grandchild.minimumSize;
22+
}
23+
}
24+
25+
return result === 0 ? 50 : result;
26+
}
27+
28+
readonly maximumSize = Number.MAX_VALUE;
29+
30+
private _onDidChange: Event<number | undefined> = Event.None;
31+
get onDidChange(): Event<number | undefined> {
32+
return this._onDidChange;
33+
}
34+
35+
protected orientation: Orientation | undefined;
36+
protected size: number | undefined;
37+
protected orthogonalSize: number | undefined;
38+
private splitview: SplitView | undefined;
39+
private children: GridNode[] = [];
40+
private color: string | undefined;
41+
42+
constructor(private parent?: GridNode, orthogonalSize?: number, color?: string) {
43+
this.orthogonalSize = orthogonalSize;
44+
this.color = color || `hsl(${Math.round(Math.random() * 360)}, 72%, 72%)`;
45+
}
46+
47+
render(container: HTMLElement): void {
48+
container = append(container, $('.node'));
49+
container.style.backgroundColor = this.color;
50+
51+
append(container, $('.action', { onclick: () => this.split(container, Orientation.HORIZONTAL) }, '⬌'));
52+
append(container, $('.action', { onclick: () => this.split(container, Orientation.VERTICAL) }, '⬍'));
53+
}
54+
55+
protected split(container: HTMLElement, orientation: Orientation): void {
56+
if (this.parent && this.parent.orientation === orientation) {
57+
const index = this.parent.children.indexOf(this);
58+
this.parent.addChild(this.size / 2, this.orthogonalSize, index + 1);
59+
} else {
60+
this.branch(container, orientation);
61+
}
62+
}
63+
64+
protected branch(container: HTMLElement, orientation: Orientation): void {
65+
this.orientation = orientation;
66+
container.innerHTML = '';
67+
68+
this.splitview = new SplitView(container, { orientation });
69+
this.layout(this.size);
70+
this.orthogonalLayout(this.orthogonalSize);
71+
72+
this.addChild(this.orthogonalSize / 2, this.size, 0, this.color);
73+
this.addChild(this.orthogonalSize / 2, this.size);
74+
}
75+
76+
layout(size: number): void {
77+
this.size = size;
78+
79+
for (const child of this.children) {
80+
child.orthogonalLayout(size);
81+
}
82+
}
83+
84+
orthogonalLayout(size: number): void {
85+
this.orthogonalSize = size;
86+
87+
if (this.splitview) {
88+
this.splitview.layout(size);
89+
}
90+
}
91+
92+
private addChild(size: number, orthogonalSize: number, index?: number, color?: string): void {
93+
const child = new GridNode(this, orthogonalSize, color);
94+
this.splitview.addView(child, size, index);
95+
96+
if (typeof index === 'number') {
97+
this.children.splice(index, 0, child);
98+
} else {
99+
this.children.push(child);
100+
}
101+
102+
this._onDidChange = anyEvent(...this.children.map(c => c.onDidChange));
103+
}
104+
}
105+
106+
export class RootGridNode extends GridNode {
107+
108+
private width: number;
109+
private height: number;
110+
111+
protected branch(container: HTMLElement, orientation: Orientation): void {
112+
if (orientation === Orientation.VERTICAL) {
113+
this.size = this.width;
114+
this.orthogonalSize = this.height;
115+
} else {
116+
this.size = this.height;
117+
this.orthogonalSize = this.width;
118+
}
119+
120+
super.branch(container, orientation);
121+
}
122+
123+
layoutBox(width: number, height: number): void {
124+
if (this.orientation === Orientation.VERTICAL) {
125+
this.layout(width);
126+
this.orthogonalLayout(height);
127+
} else if (this.orientation === Orientation.HORIZONTAL) {
128+
this.layout(height);
129+
this.orthogonalLayout(width);
130+
} else {
131+
this.width = width;
132+
this.height = height;
133+
}
134+
}
135+
}
136+
137+
export class Grid {
138+
139+
private root: RootGridNode;
140+
141+
constructor(container: HTMLElement) {
142+
this.root = new RootGridNode();
143+
this.root.render(container);
144+
}
145+
146+
layout(width: number, height: number): void {
147+
this.root.layoutBox(width, height);
148+
}
149+
}

test/grid.html

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<!DOCTYPE html>
2+
<html>
3+
4+
<head>
5+
<meta charset="utf-8" />
6+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
7+
<title>Grid Example</title>
8+
<meta name="viewport" content="width=device-width, initial-scale=1">
9+
<script src="../out/vs/loader.js"></script>
10+
<script>
11+
require.config({ baseUrl: '../out' });
12+
13+
require(['vs/base/browser/ui/splitview/grid'], ({ Grid }) => {
14+
const grid = new Grid(document.body);
15+
const layout = () => grid.layout(document.body.clientWidth, document.body.clientHeight);
16+
window.onresize = layout;
17+
layout();
18+
});
19+
</script>
20+
<style>
21+
html,
22+
body {
23+
width: 100%;
24+
height: 100%;
25+
padding: 0;
26+
margin: 0;
27+
}
28+
29+
.node {
30+
width: 100%;
31+
height: 100%;
32+
box-sizing: border-box;
33+
display: flex;
34+
align-items: center;
35+
justify-content: center;
36+
}
37+
38+
.action {
39+
display: inline-block;
40+
width: 16px;
41+
height: 16px;
42+
border: 1px solid #3c3c3c;
43+
text-align: center;
44+
line-height: 16px;
45+
border-radius: 3px;
46+
}
47+
48+
.action:hover {
49+
cursor: pointer;
50+
background-color: #ffffff54;
51+
}
52+
</style>
53+
</head>
54+
55+
<body>
56+
57+
</body>
58+
59+
</html>

0 commit comments

Comments
 (0)