Register
Essence»Wiki»Grids»Diff (17600 to 17702)
[UI Elements]() > Grids

# Introduction

Grids are UI elements designed for layouting other elements. Grids are created using [`OSGridCreate`]().

A grid has two dimensions: the number of columns, and the number of rows. Each cell in the grid can either be empty or contain one child element. Child elements are added using [`OSGridAddElement`](). Each element has an additional `layout` field which determines how it will be laid out.

A grid can have a border. This is a space between the 4 sides of the grid's boundaries and the area in which elements will be placed. A grid can also keep elements spaced apart using a constant gap between columns and rows. Some grids have a background image.

Each column in the grid can have a different width, and each row in the grid can have a different height.

![An example grid layout.](https://i.imgur.com/ymkfS56.png)

This is an example of 2x2 grid. This grid has a small border on each side, and a slightly smaller gap size. It has a background color, which makes it ideal for the placement of controls like labels. Each row has the same height, but the second column (index `1`) has a greater width than the first column (index `0`).

Grids use a simple algorithm for layouting, which occurs when it receives a `OS_MESSAGE_LAYOUT` message.
- First, it measures the size of each element by sending each a `OS_MESSAGE_MEASURE` message.
- It finds the widest element in each column, and makes that the width of the column.
- It finds the tallest element in each row, and makes that the height of the row.
- Each element is then sent their bounds through a `OS_MESSAGE_LAYOUT` message.

There are a few complications to this however.

## Cell layouts

Each element has an additional `layout` field which determines what happens when the cell bounds it receives are greater than its preferred size. The `layout` field is a combination of `OS_CELL_` flags.
- `OS_CELL_H_EXPAND`: regardless of the preferred width, use the cell bounds
- `OS_CELL_H_LEFT`: align the element to the left of the cell bounds
- `OS_CELL_H_CENTER`: align the element to the center of the cell bounds
- `OS_CELL_H_RIGHT`: align the element to the right of the cell bounds
- `OS_CELL_V_EXPAND`: regardless, of the preferred height, use the cell bounds
- `OS_CELL_V_TOP`: align the element to the top of the cell bounds
- `OS_CELL_V_CENTER`: align the element to the center of the cell bounds (beware: this may prove confusing to CSS developers)
- `OS_CELL_V_BOTTOM`: align the element to the bottom of the cell bounds

![An example of cell layouts.](https://i.imgur.com/BXeTR5A.png)

This example shows the following cell layouts from left to right:
- `OS_CELL_H_EXPAND | OS_CELL_V_EXPAND`
- `OS_CELL_H_EXPAND | OS_CELL_V_BOTTOM`
- `OS_CELL_H_RIGHT | OS_CELL_V_CENTER`

## Pushing

It's common to want an element to fill as much of its parent element as possible, so that when the window is resized its contents will match the new size.

![An image of the file manager demonstrating this.](https://i.imgur.com/b1wZdZo.png)

In this image of the file manager we can see that the toolbars at the top and the status bar at the bottom fill the horizontal width of the window, the path textbox fills the remaining horizontal width of the first toolbar, the bookmarks list fills the remaining vertical height of the window, and the folder listing fills the rest of the window.

This is done using the push layout flags.
- `OS_CELL_H_PUSH`: use up all remaining horizontal space in a grid
- `OS_CELL_V_PUSH`: use up all remaining vertical space in a grid

After the non-pushed columns and rows have been sized, the remaining space will be divided up equally among all the pushed columns and rows.

![An example from the calculator.](https://i.imgur.com/ZnYl3mp.png)

In the calculator all of the buttons use the flags `OS_CELL_H_PUSH | OS_CELL_V_PUSH | OS_CELL_H_EXPAND | OS_CELL_V_EXPAND`. Therefore they evenly divide up all the space in the window. Note that the expand flags are still necessary; the push flags affect the size of the cells rather than the preferred size of the elements.

# Using grids

# Reference

## OSGridAddElement

```c
void OSGridAddElement(OSObject grid, unsigned column, unsigned row, OSObject control, unsigned layout);
```

Add an element to a grid, at a given `column` and `row`, and using a given `layout`.


The available layout flags are:
- `OS_CELL_H_EXPAND`: regardless of the preferred width, use the cell bounds
- `OS_CELL_H_LEFT`: align the element to the left of the cell bounds
- `OS_CELL_H_CENTER`: align the element to the center of the cell bounds
- `OS_CELL_H_RIGHT`: align the element to the right of the cell bounds
- `OS_CELL_H_PUSH`: use up all remaining horizontal space in a grid
- `OS_CELL_H_INDENT_1`: indent the element slightly
- `OS_CELL_H_INDENT_2`: indent the element a bit more
- `OS_CELL_V_EXPAND`: regardless, of the preferred height, use the cell bounds
- `OS_CELL_V_TOP`: align the element to the top of the cell bounds
- `OS_CELL_V_CENTER`: align the element to the center of the cell bounds (beware: this may prove confusing to CSS developers)
- `OS_CELL_V_BOTTOM`: align the element to the bottom of the cell bounds
- `OS_CELL_V_PUSH`: use up all remaining vertical space in a grid
- `OS_CELL_HIDDEN`: hide the element

And the following combination flags are also available:
- `OS_CELL_FILL`: `OS_CELL_H_EXPAND | OS_CELL_V_EXPAND | OS_CELL_H_PUSH | OS_CELL_V_PUSH`
- `OS_CELL_H_FILL`: `OS_CELL_H_EXPAND | OS_CELL_H_PUSH`
- `OS_CELL_V_FILL`: `OS_CELL_V_EXPAND | OS_CELL_V_PUSH`
- `OS_CELL_CENTER`: `OS_CELL_H_CENTER | OS_CELL_V_CENTER`
- `OS_CELL_EXPAND`: `OS_CELL_H_EXPAND | OS_CELL_V_EXPAND`

## OSGridCreate

```c
OSObject OSGridCreate(unsigned columns, unsigned rows, OSGridStyle *style);
```

Create a grid with a given number of `columns` and `rows`.

The `style` can be one of the following defaults:
- `OS_GRID_STYLE_GROUP_BOX`: a group box, with a small border and gap
- `OS_GRID_STYLE_LAYOUT`: no border or gap
- `OS_GRID_STYLE_CONTAINER`: a small border and gap
- `OS_GRID_STYLE_CONTAINER_WITHOUT_BORDER`: a gap
- `OS_GRID_STYLE_CONTAINER_ALT`: a container for placing dialog command buttons
- `OS_GRID_STYLE_STATUS_BAR`: a status bar, with a small border and gap
- `OS_GRID_STYLE_TOOLBAR`: a toolbar
- `OS_GRID_STYLE_TOOLBAR_ALT`: a secondary toolbar
- `OS_GRID_STYLE_TAB_PANE_CONTENT`: the content of a tab

Or can be configured manually:

```c
struct OSGridStyle {
OSRectangle borderSize;
uint32_t gapSize, backgroundColor, preferredWidth, preferredHeight;
OSUIImage *backgroundImage;
bool noclip; // Don't clip children.
};
```
[UI Elements]() > Grids

# Introduction

Grids are UI elements designed for layouting other elements. Grids are created using [`OSGridCreate`]().

A grid has two dimensions: the number of columns, and the number of rows. Each cell in the grid can either be empty or contain one child element. Child elements are added using [`OSGridAddElement`](). Each element has an additional `layout` field which determines how it will be laid out.

A grid can have a border. This is a space between the 4 sides of the grid's boundaries and the area in which elements will be placed. A grid can also keep elements spaced apart using a constant gap between columns and rows. Some grids have a background image.

Each column in the grid can have a different width, and each row in the grid can have a different height.

![An example grid layout.](https://i.imgur.com/ymkfS56.png)

This is an example of 2x2 grid. This grid has a small border on each side, and a slightly smaller gap size. It has a background color, which makes it ideal for the placement of controls like labels. Each row has the same height, but the second column (index `1`) has a greater width than the first column (index `0`).

Grids use a simple algorithm for layouting, which occurs when it receives a `OS_MESSAGE_LAYOUT` message.
- First, it measures the size of each element by sending each a `OS_MESSAGE_MEASURE` message.
- It finds the widest element in each column, and makes that the width of the column.
- It finds the tallest element in each row, and makes that the height of the row.
- Each element is then sent their bounds through a `OS_MESSAGE_LAYOUT` message.

There are a few complications to this however.

## Cell layouts

Each element has an additional `layout` field which determines what happens when the cell bounds it receives are greater than its preferred size. The `layout` field is a combination of `OS_CELL_` flags.
- `OS_CELL_H_EXPAND`: regardless of the preferred width, use the cell bounds
- `OS_CELL_H_LEFT`: align the element to the left of the cell bounds
- `OS_CELL_H_CENTER`: align the element to the center of the cell bounds
- `OS_CELL_H_RIGHT`: align the element to the right of the cell bounds
- `OS_CELL_V_EXPAND`: regardless, of the preferred height, use the cell bounds
- `OS_CELL_V_TOP`: align the element to the top of the cell bounds
- `OS_CELL_V_CENTER`: align the element to the center of the cell bounds (beware: this may prove confusing to CSS developers)
- `OS_CELL_V_BOTTOM`: align the element to the bottom of the cell bounds

![An example of cell layouts.](https://i.imgur.com/BXeTR5A.png)

This example shows the following cell layouts from left to right:
- `OS_CELL_H_EXPAND | OS_CELL_V_EXPAND`
- `OS_CELL_H_EXPAND | OS_CELL_V_BOTTOM`
- `OS_CELL_H_RIGHT | OS_CELL_V_CENTER`

## Pushing

It's common to want an element to fill as much of its parent element as possible, so that when the window is resized its contents will match the new size.

![An image of the file manager demonstrating this.](https://i.imgur.com/b1wZdZo.png)

In this image of the file manager we can see that the toolbars at the top and the status bar at the bottom fill the horizontal width of the window, the path textbox fills the remaining horizontal width of the first toolbar, the bookmarks list fills the remaining vertical height of the window, and the folder listing fills the rest of the window.

This is done using the push layout flags.
- `OS_CELL_H_PUSH`: use up all remaining horizontal space in a grid
- `OS_CELL_V_PUSH`: use up all remaining vertical space in a grid

After the non-pushed columns and rows have been sized, the remaining space will be divided up equally among all the pushed columns and rows.

![An example from the calculator.](https://i.imgur.com/ZnYl3mp.png)

In the calculator all of the buttons use the flags `OS_CELL_H_PUSH | OS_CELL_V_PUSH | OS_CELL_H_EXPAND | OS_CELL_V_EXPAND`. Therefore they evenly divide up all the space in the window. Note that the expand flags are still necessary; the push flags affect the size of the cells rather than the preferred size of the elements.

# Using grids

# Reference

## OSGridAddElement

```c
void OSGridAddElement(OSObject grid, unsigned column, unsigned row, OSObject control, unsigned layout);
```

Add an element to a grid, at a given `column` and `row`, and using a given `layout`. The cell must not be occupied.
The available layout flags are:
- `OS_CELL_H_EXPAND`: regardless of the preferred width, use the cell bounds
- `OS_CELL_H_LEFT`: align the element to the left of the cell bounds
- `OS_CELL_H_CENTER`: align the element to the center of the cell bounds
- `OS_CELL_H_RIGHT`: align the element to the right of the cell bounds
- `OS_CELL_H_PUSH`: use up all remaining horizontal space in a grid
- `OS_CELL_H_INDENT_1`: indent the element slightly
- `OS_CELL_H_INDENT_2`: indent the element a bit more
- `OS_CELL_V_EXPAND`: regardless, of the preferred height, use the cell bounds
- `OS_CELL_V_TOP`: align the element to the top of the cell bounds
- `OS_CELL_V_CENTER`: align the element to the center of the cell bounds (beware: this may prove confusing to CSS developers)
- `OS_CELL_V_BOTTOM`: align the element to the bottom of the cell bounds
- `OS_CELL_V_PUSH`: use up all remaining vertical space in a grid
- `OS_CELL_HIDDEN`: hide the element

And the following combination flags are also available:
- `OS_CELL_FILL`: `OS_CELL_H_EXPAND | OS_CELL_V_EXPAND | OS_CELL_H_PUSH | OS_CELL_V_PUSH`
- `OS_CELL_H_FILL`: `OS_CELL_H_EXPAND | OS_CELL_H_PUSH`
- `OS_CELL_V_FILL`: `OS_CELL_V_EXPAND | OS_CELL_V_PUSH`
- `OS_CELL_CENTER`: `OS_CELL_H_CENTER | OS_CELL_V_CENTER`
- `OS_CELL_EXPAND`: `OS_CELL_H_EXPAND | OS_CELL_V_EXPAND`

## OSGridCreate

```c
OSObject OSGridCreate(unsigned columns, unsigned rows, OSGridStyle *style);
```

Create a grid with a given number of `columns` and `rows`.

The `style` can be one of the following defaults:
- `OS_GRID_STYLE_GROUP_BOX`: a group box, with a small border and gap
- `OS_GRID_STYLE_LAYOUT`: no border or gap
- `OS_GRID_STYLE_CONTAINER`: a small border and gap
- `OS_GRID_STYLE_CONTAINER_WITHOUT_BORDER`: a gap
- `OS_GRID_STYLE_CONTAINER_ALT`: a container for placing dialog command buttons
- `OS_GRID_STYLE_STATUS_BAR`: a status bar, with a small border and gap
- `OS_GRID_STYLE_TOOLBAR`: a toolbar
- `OS_GRID_STYLE_TOOLBAR_ALT`: a secondary toolbar
- `OS_GRID_STYLE_TAB_PANE_CONTENT`: the content of a tab

Or can be configured manually:

```c
struct OSGridStyle {
OSRectangle borderSize;
uint32_t gapSize, backgroundColor, preferredWidth, preferredHeight;
OSUIImage *backgroundImage;
bool noclip; // Don't clip children.
};
```