Container controls and layout systems for organizing and positioning 2D GUI elements including grids, stack panels, and scroll viewers.
Base container control for grouping multiple controls together.
class Container extends Control {
addControl(control: Control): Container;
removeControl(control: Control): Container;
removeControlByName(name: string): Container;
getChildByName(name: string): Nullable<Control>;
getChildByType<T extends Control>(name: string, type: new (...args: any[]) => T): Nullable<T>;
getDescendants(directDescendantsOnly?: boolean, predicate?: (control: Control) => boolean): Control[];
clearControls(): void;
background: string;
adaptWidthToChildren: boolean;
adaptHeightToChildren: boolean;
}Usage Examples:
import { Container, Button, TextBlock } from "@babylonjs/gui";
// Create container
const container = new Container("myContainer");
container.widthInPixels = 300;
container.heightInPixels = 200;
container.background = "#333333";
// Add controls
const title = new TextBlock("title", "Settings");
const button = Button.CreateSimpleButton("ok", "OK");
container.addControl(title);
container.addControl(button);
// Find child controls
const foundButton = container.getChildByName("ok");
const allButtons = container.getDescendants(false, (control) => control instanceof Button);Advanced grid layout system with row and column definitions for precise control positioning.
class Grid extends Container {
addRowDefinition(height: number, isPixel?: boolean): Grid;
addColumnDefinition(width: number, isPixel?: boolean): Grid;
setRowDefinition(index: number, height: number, isPixel?: boolean): Grid;
setColumnDefinition(index: number, width: number, isPixel?: boolean): Grid;
getRowDefinition(index: number): Nullable<ValueAndUnit>;
getColumnDefinition(index: number): Nullable<ValueAndUnit>;
addControl(control: Control, row?: number, column?: number): Grid;
removeControl(control: Control): Grid;
getChildrenAt(row: number, column: number): Control[];
getRowCount(): number;
getColumnCount(): number;
}Usage Examples:
import { Grid, Button, TextBlock } from "@babylonjs/gui";
// Create grid with 3 rows and 2 columns
const grid = new Grid("myGrid");
grid.widthInPixels = 400;
grid.heightInPixels = 300;
// Define rows (30px, flexible, 50px)
grid.addRowDefinition(30, true); // Fixed 30 pixels
grid.addRowDefinition(1, false); // 1 fraction (flexible)
grid.addRowDefinition(50, true); // Fixed 50 pixels
// Define columns (50%, 50%)
grid.addColumnDefinition(0.5, false); // 50%
grid.addColumnDefinition(0.5, false); // 50%
// Add controls to specific cells
const header = new TextBlock("header", "Title");
grid.addControl(header, 0, 0); // First row, first column
const button1 = Button.CreateSimpleButton("btn1", "Button 1");
grid.addControl(button1, 1, 0); // Second row, first column
const button2 = Button.CreateSimpleButton("btn2", "Button 2");
grid.addControl(button2, 1, 1); // Second row, second column
const footer = new TextBlock("footer", "Status: Ready");
grid.addControl(footer, 2, 0); // Third row, spans both columnsLinear layout container that stacks controls vertically or horizontally.
class StackPanel extends Container {
isVertical: boolean;
spacing: string | number;
ignoreLayoutWarnings: boolean;
// Inherited from Container
adaptWidthToChildren: boolean;
adaptHeightToChildren: boolean;
}Usage Examples:
import { StackPanel, Button, TextBlock } from "@babylonjs/gui";
// Create vertical stack panel
const verticalStack = new StackPanel("vStack");
verticalStack.isVertical = true;
verticalStack.spacing = 10;
verticalStack.adaptHeightToChildren = true;
verticalStack.widthInPixels = 200;
// Add buttons vertically
const buttons = ["Home", "Settings", "Help", "Exit"];
buttons.forEach((text, index) => {
const button = Button.CreateSimpleButton(`btn${index}`, text);
button.heightInPixels = 40;
verticalStack.addControl(button);
});
// Create horizontal stack panel
const horizontalStack = new StackPanel("hStack");
horizontalStack.isVertical = false;
horizontalStack.spacing = 5;
horizontalStack.adaptWidthToChildren = true;
horizontalStack.heightInPixels = 50;
// Add controls horizontally
const label = new TextBlock("label", "Volume:");
const volumeSlider = new Slider("volume");
volumeSlider.widthInPixels = 100;
horizontalStack.addControl(label);
horizontalStack.addControl(volumeSlider);Scrollable container for content that exceeds the visible area.
class ScrollViewer extends Rectangle {
scrollBackground: string;
barSize: number;
barColor: string;
barImage: string;
thumbLength: number;
thumbHeight: number;
barImageHeight: number;
horizontalBar: ScrollBar;
verticalBar: ScrollBar;
wheelPrecision: number;
readonly window: ScrollViewerWindow;
setBucketSizes(width: number, height: number): void;
}
class ScrollViewerWindow extends Container {
parentClientWidth: number;
parentClientHeight: number;
bucketWidth: number;
bucketHeight: number;
}
class ScrollBar extends Control {
borderColor: string;
background: string;
thumbLength: number;
thumbHeight: number;
barOffset: number;
isVertical: boolean;
minimum: number;
maximum: number;
value: number;
step: number;
onValueChangedObservable: Observable<number>;
}Usage Examples:
import { ScrollViewer, StackPanel, TextBlock } from "@babylonjs/gui";
// Create scroll viewer
const scrollViewer = new ScrollViewer("scrollArea");
scrollViewer.widthInPixels = 300;
scrollViewer.heightInPixels = 200;
scrollViewer.barSize = 20;
scrollViewer.barColor = "#666666";
scrollViewer.scrollBackground = "#333333";
// Create content that exceeds scroll area
const contentStack = new StackPanel("content");
contentStack.isVertical = true;
contentStack.spacing = 5;
contentStack.adaptHeightToChildren = true;
contentStack.widthInPixels = 280;
// Add many items to demonstrate scrolling
for (let i = 0; i < 20; i++) {
const item = new TextBlock(`item${i}`, `List Item ${i + 1}`);
item.heightInPixels = 30;
item.textHorizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
contentStack.addControl(item);
}
// Add content to scroll viewer
scrollViewer.addControl(contentStack);
// Handle scroll events
scrollViewer.verticalBar.onValueChangedObservable.add((value) => {
console.log("Vertical scroll position:", value);
});Controls for handling multi-line text and path-based layouts.
class MultiLine extends Control {
dash: number[];
points: MultiLinePoint[];
add(...items: (Control | MultiLinePoint)[]): MultiLine;
push(item?: Control | MultiLinePoint): MultiLine;
remove(value: Control | MultiLinePoint): MultiLine;
getAt(index: number): MultiLinePoint;
onPointUpdate(): void;
}
class MultiLinePoint {
constructor(multiLine: MultiLine);
x: string | number;
y: string | number;
control: Nullable<Control>;
translate(x: number, y: number): MultiLinePoint;
dispose(): void;
}Usage Examples:
import { MultiLine, MultiLinePoint, Rectangle } from "@babylonjs/gui";
// Create multi-line path
const multiLine = new MultiLine("path");
multiLine.lineWidth = 3;
multiLine.color = "white";
multiLine.dash = [10, 5]; // Dashed line
// Add points
const point1 = new MultiLinePoint(multiLine);
point1.x = 50;
point1.y = 50;
const point2 = new MultiLinePoint(multiLine);
point2.x = 150;
point2.y = 100;
const point3 = new MultiLinePoint(multiLine);
point3.x = 100;
point3.y = 150;
multiLine.add(point1, point2, point3);
// Attach controls to points
const marker = new Rectangle("marker");
marker.widthInPixels = 10;
marker.heightInPixels = 10;
marker.background = "red";
point2.control = marker;// Grid definition interface
interface IGridDefinition {
value: number;
isPixel: boolean;
}
// Scroll viewer bucket interface
interface IBucketInfo {
bucketWidth: number;
bucketHeight: number;
}
// Layout constants
const Container: {
LAYOUT_CANVAS: number;
LAYOUT_HORIZONTAL_STACK_PANEL: number;
LAYOUT_VERTICAL_STACK_PANEL: number;
};