Skip to content

Layout

namespace Griff.Scenes;
public sealed class Layout : Component, IClipsChildren, IDrawEffect

Lines up the entity’s children in a list or a grid, so nothing has to place them: a board of offer cards, a list of quest rows, a shop’s shelf. They take their places in hierarchy order from the top left corner of its Size, whatever their own positions: one spawned into it (Game.Spawn("Card", board)) goes after the last, and when one is destroyed or hidden the rest close up. With Clip what doesn’t fit is cut off at its edges and the mouse wheel scrolls it. With Reorderable the player drags them into a new order: a queue, a build list. With Slide they slide to their new places rather than jumping there.

A child takes the room of its Button’s clickable area, its Sprite’s size or its own Layout’s, whichever is biggest, times its scale; a child with only text takes what its letters are guessed to. Set CellSize to give every child the same room. Put the background on the layout’s own entity: every child showing is placed. In the Scene view children are put in place as you edit; a child’s own position is overwritten.

This is a component: its saved properties are on its component page.

public Vector2 CellSize { get; set; }

The room every child takes, in world units: (2, 3) for cards that size. 0 (either way) measures each child: its Button’s clickable area, its Sprite’s size or its own Layout’s, whichever is biggest, times its scale.

public bool Clip { get; set; }

Cut the children off at the edges of its Size, and scroll them with the mouse wheel over it when there are more than fit (or from a script with Scroll).

public int Columns { get; set; }

How many children a grid row holds before the next row starts.

public LayoutDirection Direction { get; set; }

Which way the children go: down a list, across a row, or in a grid of Columns.

public string? GrabAction { get; set; }

The input action that lifts the picked button’s row to move it with the arrows (or the D-pad), and puts it down again, e.g. “Interact” (E or the gamepad’s Y). Empty leaves reordering to the mouse.

public Entity? Held { get; }

The row being dragged or moved with keys, or null.

public float MostScroll { get; }

How far it can scroll: how much more the children take up than there’s room for. 0 when they all fit.

public float Padding { get; set; }

The space between its edges and the children, in world units.

public string? ReorderMessage { get; set; }

A message sent with Game.Send when a row is put in a new place, with the row as its data.

public bool Reorderable { get; set; }

Let the player put its children in a new order: press on one and drag it along the list (or about the grid), the others sliding to make room where it would land, and let go to put it there, which raises Reordered. A press that doesn’t move still clicks a Button on it; Esc, or letting go outside it, puts the row back. Dragged near the end of one that Clips, it scrolls. With keys or a controller, GrabAction lifts the row of the button picked, the arrows move it and a second press (or Enter or A) puts it down.

public IReadOnlyList<Entity> Rows { get; }

Its rows: the children it shows (not those hidden), in their order, as Reordered and Move count them from 0.

public string? SaveOrderAs { get; set; }

A name in Game.SaveData to keep the order in: the rows’ names, separated by commas, saved as the player changes it and put back whenever rows with those names are in it (rows made again from a table, a game loaded). Rows it doesn’t name keep their places. Empty keeps no order. Give each row its own name for it to work.

public float Scroll { get; set; }

How far it’s scrolled, in world units from the start (down a list or grid, along a row), from 0 to MostScroll. The mouse wheel changes it while Clip is on; scripts can set it.

public float ScrollStep { get; }

How far one turn of the mouse wheel scrolls it: a row of children.

public Vector2 Size { get; set; }

Its area, centered on the entity, in world units before the transform’s scale: the children start at its top left corner (inside the Padding), and with Clip they’re cut off at its edges. Without Clip children that don’t fit go on past it.

public bool Slide { get; set; }

While the game runs, its children slide to their new places rather than jumping there, over SlideTime: the rest closing up when one is destroyed or hidden, making room for one added, moving as they’re put in a new order or scrolled. One that’s just been added (or shown) is put in its place at once.

public float SlideTime { get; set; }

Seconds its children take to slide into new places (with Slide), and, while it’s Reorderable, the other rows out of the way and a let-go row into its place. 0 jumps.

public float Spacing { get; set; }

The gap between one child and the next, in world units.

public Box WorldArea { get; }

Its Size in the world, where it is now (as drawn, while it’s being drawn): the box round it, rotation and all.

public void Arrange()

Puts its children in their places now, as it does by itself every frame (just after LateUpdate) and in the Scene view as it’s edited: for a script that spawns a child and wants to know where it went straight away.

public static void ArrangeAll(Scene scene)

Puts every layout’s children in scene in their places (see Arrange).

public void Move(Entity row, int to)

Puts row, one of its Rows, at place to among them (0 the first; past the end puts it last), the rest closing up and making room, and raises Reordered: for ▲ and ▼ buttons, or a script sorting a queue.

public static void MoveIn<T>(IList<T> list, int from, int to)

Moves the item at from in list to to, as Reordered moved a row: layout.Reordered += (row, from, to) => Layout.MoveIn(queue, from, to); keeps a script’s list in the rows’ order.

public event Action<Entity, int, int>? Reordered

Raised when a row is put in a new place, by the player or Move: the row, the place it was in and the one it’s in now, each counted from 0 among its Rows. A script keeping a list in the same order moves its own with MoveIn.