Drafter.LayerCompositor (drafter v0.3.1)

Copy Markdown View Source

Composites independently rendered layers into a single list of strips.

A layer is create_layer/5: an id, the strips to draw, the bounds they occupy within the viewport, a z_index, and an opacity. composite/2 draws the layers onto a blank viewport in ascending z_index order, each at its own bounds, so a higher z_index covers a lower one. Segment styling is preserved and translucent styles are blended against what they cover.

The named constructors fix the z_index for the usual roles:

Summary

Functions

A layer at z_index 0, beneath every other layer these constructors make.

Composite a translucent style onto whatever it covers.

A layer at z_index 30, above content and above widgets at the default z_base.

Draw layers onto a blank viewport and return one strip per viewport row.

Recompose only the viewport rows in dirty_rows, reusing previous_composite.

A layer at z_index 10, above the background and below chrome.

A layer for a widget, at a z_index derived from its id and module.

Types

bounds()

@type bounds() :: %{x: integer(), y: integer(), width: integer(), height: integer()}

composition_result()

@type composition_result() :: [Drafter.Draw.Strip.t()]

layer()

@type layer() :: %{
  id: term(),
  z_index: integer(),
  strips: [Drafter.Draw.Strip.t()],
  bounds: bounds(),
  opacity: float()
}

viewport()

@type viewport() :: %{width: integer(), height: integer()}

Functions

background_layer(strips, bounds)

@spec background_layer([Drafter.Draw.Strip.t()] | nil, bounds()) :: layer()

A layer at z_index 0, beneath every other layer these constructors make.

Its id is always :background.

blend_over(style, beneath)

Composite a translucent style onto whatever it covers.

An :opacity of 1.0 is opaque and 0.0 leaves only what is underneath. Returns style unchanged when it carries no :opacity; the key is removed from the returned style either way.

chrome_layer(id, strips, bounds)

@spec chrome_layer(term(), [Drafter.Draw.Strip.t()] | nil, bounds()) :: layer()

A layer at z_index 30, above content and above widgets at the default z_base.

composite(layers, viewport)

@spec composite([layer()], viewport()) :: composition_result()

Draw layers onto a blank viewport and return one strip per viewport row.

viewport is %{width: w, height: h}. Layers are drawn in ascending z_index order, each at its own bounds; parts falling outside the viewport are dropped. Always returns viewport.height strips, each viewport.width columns wide.

composite_incremental(layers, viewport, previous_composite, dirty_rows)

@spec composite_incremental(
  [map()],
  viewport(),
  [Drafter.Draw.Strip.t()],
  MapSet.t(non_neg_integer())
) ::
  [Drafter.Draw.Strip.t()]

Recompose only the viewport rows in dirty_rows, reusing previous_composite.

dirty_rows holds zero-based viewport row indices. Rows not listed are taken from previous_composite, or left blank where it is shorter than the viewport. An empty dirty_rows returns previous_composite untouched.

The caller is responsible for dirty_rows covering every row that changed; rows omitted keep whatever they showed before.

content_layer(id, strips, bounds)

@spec content_layer(term(), [Drafter.Draw.Strip.t()] | nil, bounds()) :: layer()

A layer at z_index 10, above the background and below chrome.

create_layer(id, strips, bounds, z_index \\ 0, opacity \\ 1.0)

@spec create_layer(
  term(),
  [Drafter.Draw.Strip.t()] | nil,
  bounds(),
  integer(),
  float()
) :: layer()

Build a layer.

  • id — identifier, unique among the layers composited together
  • strips — the rows to draw, top to bottom; nil is taken as []
  • bounds%{x: x, y: y, width: w, height: h}, where the strips are drawn
  • z_index — draw order, higher covering lower, default 0
  • opacity0.0 to 1.0, default 1.0

No validation is performed; the values are stored as given.

widget_layer(widget_id, strips, bounds, z_base \\ 0, widget_module \\ nil, opacity \\ 1.0)

@spec widget_layer(
  term(),
  [Drafter.Draw.Strip.t()] | nil,
  bounds(),
  integer(),
  module() | nil,
  float()
) ::
  layer()

A layer for a widget, at a z_index derived from its id and module.

z_base is added to an offset chosen by the first rule that applies: 50 for an id whose name begins "footer", 40 for one beginning "header", 10 for a container module (Drafter.Widget.Box, Card, Collapsible, ScrollableContainer), and 20 otherwise.

widget_module may be nil, in which case the container rule cannot apply. The id prefix rules match on the id rendered as a string, so both :footer_bar and "footer_bar" take the footer offset.

z_base defaults to 0 and opacity to 1.0.