# `Atui.Screen`
[🔗](https://github.com/iboard/atui/blob/v0.3.0/lib/atui/screen.ex#L1)

A fixed-size grid of terminal cells that views draw into.

Every write is clipped to the screen bounds, so a view can never corrupt the
frame by drawing past its own edges. Screens compose: a view renders into a
screen the size of its rect, and the runtime overlays that onto the frame.

Each cell holds a grapheme and an `Atui.Style`. Styles stay data until the
very last moment — `to_iodata/1` emits an escape sequence only where the style
changes from the cell before it, and `to_text/1` drops them entirely, which is
what tests assert against.

# `cell`

```elixir
@type cell() :: {String.t(), Atui.Style.t() | nil}
```

# `t`

```elixir
@type t() :: %Atui.Screen{
  cells: %{required({integer(), integer()}) =&gt; cell()},
  height: non_neg_integer(),
  width: non_neg_integer()
}
```

# `box`

Draws a box border around `rect`.

Options:

  * `:title` — centred in the top border, e.g. `" Atui v0.1.0 "`
  * `:chars` — border charset: `:single` (default), `:double` or `:round`
  * `:style` — an `Atui.Style` for the border and the fill
  * `:title_style` — an `Atui.Style` for the title (defaults to `:style`)
  * `:fill` — blank the interior first (default `true`), so a popup hides
    whatever it is drawn over

# `cell`

The cell at `{x, y}` as `{grapheme, style}`, or `nil` if out of bounds.

# `fill`

Fills `rect` with `grapheme` (a space by default).

# `new`

A blank screen of the given size.

# `overlay`

Copies every cell of `other` onto `base`, offset by `{x, y}`.

# `put`

Writes a single grapheme, ignoring out-of-bounds coordinates.

# `put_lines_centered`

Vertically centres `lines` inside `rect`, each horizontally centred.

# `put_text`

Writes `text` starting at `{x, y}`, clipped to the screen.

# `put_text_centered`

Writes `text` horizontally centred on row `y` within `rect`.

# `put_text_right`

```elixir
@spec put_text_right(
  t(),
  Atui.Rect.t(),
  integer(),
  String.t(),
  Atui.Style.t() | nil,
  non_neg_integer()
) :: t()
```

Writes `text` right-aligned on row `y` within `rect`.

`margin` is the columns to leave clear at the right-hand end, which is how a
label sits *inside* a border rather than on it: `2` keeps the border column
and one character of border showing beyond the text, the way a `box/3` title
is written with a space at each end.

`y` is a row of the screen, as it is in `put_text_centered/5`; `rect` decides
only where the text ends.

# `rect`

The full extent of the screen as a rect.

# `restyle`

Restyles the cells in `rect`, keeping whatever graphemes are already there.

# `restyle_border`

Restyles the outline of `rect` — a focus ring around whatever is drawn there.

It recolours cells rather than drawing a border, so a container can mark one
of its children without knowing how that child chose to frame itself.

# `to_iodata`

Renders the screen as iodata: graphemes, escape sequences, rows separated by
CRLF.

CRLF (not LF) because the terminal is in raw mode: without the carriage
return the cursor stays in whatever column the previous row ended on. Each row
ends in the default style, so a coloured background cannot leak into the next.

# `to_string`

The rendered screen as a binary, escape sequences included.

# `to_text`

The screen as plain text, one row per line, with every style dropped.

This is the view a person would see, which makes it what assertions want.

# `truncate`

Truncates `text` to at most `width` graphemes.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
