or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

2d-controls.md2d-layout.md3d-controls.md3d-materials.mdindex.mdinput-controls.mdutilities.md
tile.json

2d-layout.mddocs/

2D Layout

Container controls and layout systems for organizing and positioning 2D GUI elements including grids, stack panels, and scroll viewers.

Capabilities

Container

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);

Grid Layout

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 columns

Stack Panel

Linear 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);

Scroll Viewer

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);
});

Multi-Line Controls

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;

Types and Interfaces

// 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;
};