1.0.1 • Published 11 months ago

@potch/playout v1.0.1

Weekly downloads
-
License
-
Repository
-
Last release
11 months ago

Playout

UI library and box model for Playdate

Support this project on Itch.io 🕹

Installation

If you are using toybox, you can run

toybox add potch/playout

Otherwise the library is a single file you can clone/copy into your project.

Demo

If you'd like to run the demo, you'll need the Playdate SDK. Then run:

pdc demo

and open the resulting packaged in the Playdate Simulator.

If you want to develop/experiment on the library or demo and you have node installed you can run the following:

npm install
npm start

Which will build and launch the demo, and re-build after any changes.

API Docs

playout.box

Box-based layout element. supports 1-dimensional layout (horizontal or vertical) with 2-dimensional alignment and flexible sizing.

Methods

playout.box.new(properties, [children])

Creates a new playout.box. Takes a table of properties and a list of children.

Children can be other boxes, images, or text.

Returns a playout.box.

Supported properties:

propertydescriptiondefault value
backgroundAlphaopacity of box fill, drawn as a dither pattern.0 (full)
backgroundColorcolor to fill the box when drawingnil (transparent)
borderthickness of border on box0
borderColorcolor of border (if > 0)playdate.graphics.kColorBlack
borderRadiuscorner radius to use when drawing the box0
directiondirection of layout. can be horizontal (children will be in a row) or vertical (children will be in a column)playout.kDirectionVertical
flexif set (non-zero), box will grow proporitonally to fill extra layout space in its parent.nil
fontfont to use when drawing text in children.nil (default)
fontFamilyfont family to use when drawing text in children. takes precedence over font, and allows for rich formatting.nil
hAlignhow to horizontally align children. see Alignmentplayout.kAlignCenter
heightheight of the box. if not specified, box will be the height of its contents plus padding, spacing, etc. (but no larger than maxHeight)nil
idunique string used for lookups via playout.tree.getnil
maxHeightmaximum height of the box240
maxWidthmaximum width of the box400
minHeightminimum height of the box1
minWidthminimum width of the box1
paddingamount of inset, in pixels, between box children and the edge0
paddingBottombottom padding. defaults to paddingTop or padding value if provided, in that ordernil
paddingLeftleft padding. defaults to padding value if provided, in that ordernil
paddingRightright padding. defaults to paddingLeft or padding value if provided, in that ordernil
paddingToptop padding. defaults to padding value if providednil
selfAlignoverride the box alignment from that provided by its parent. if parent's direction is horizontal, affects vertical alignment, if vertical, affects horizontal alignmentnil (no override)
shadowsize of shadow in pixels to draw under the box. note the shadow subtracts from the overall available height of the boxnil (no shaow)
shadowAlphahow "dark" the shadow is, from 0..1. drawn using dither.0 (full opacity)
spacinghow much space should be between each child of the box0
stylesee Style Reusenill
tabIndexdefines position for sequential lookups by playout.tree.tabIndex.nil
vAlignhow to vertically align children. see Alignmentplayout.kAlignCenter
widthwidth of the box. if not specified, box will be the width of its contents plus padding, spacing, etc. (but no larger than maxWidth)nil

playout.box:appendChild(child)

Add a child (text, image, or other box) to the box.

playout.box:insertChild(child, position)

Add a child (text, image, or other box) to the box at a specified position. e.g. insertChild(child, 1) would add the child as the first child.

playout.box:layout([context])

Computes the layout of the box and all children recursively. Returns a playout.geometry.rect with the computed size. Usually indirectly called by playout.tree:layout.

context is a table with the following properties:

propertydescriptiondefault
maxWidthmaximum width the box can be, regardless of its contentsmath.huge (no limit)
maxHeightmaximum height the box can be, regardless of its contentmath.huge (no limit)

playout.box:draw(rect)

Draw the box and all its children using their visual properties in the current drawing context within the specified rect. Usually called indirectly by playout.tree.draw with pre-computed rects generated during :layout.

properties

playout.box.properties

table of properties, provided via initial creation.

playout.box.children

list of children, managed via appendChild, insertChild, or playout.tree.

playout.box.childRects

List of rects corresponding to children, determined during :layout. Will be nil if layout hasn't been called yet.

playout.box.parent

Reference to a parent box, if any. set by appendChild, insertChild, or playout.tree. If children were changed directly via .children, their parent will not be set. read only.

playout.box.style

see Style Reuse.

playout.text

Layout element for text content. supports fonts, outlines, and text wrapping.

methods

playout.text.new(text, [properties])

Creates a new playout.text. Takes a string of text and an optional table of properties.

Returns a playout.text

Supported properties:

propertydescriptiondefault
fontwhich playdate.graphics.font to use to render text. this property can be inherited from parent boxes.nil (currently set font),
fontFamilywhich playdate.graphics.fontFamily to use to render text. allows for rich text formatting. If set, overrides font. this property can be inherited from parent boxes.nil,
alignmenttext alignmentkTextAlignment.left,
leadingleading adjusmentnil (none),
flexif set (non-zero), text will grow proporitonally to fill extra layout space in its parent.nil,
wrapwhether to line-wrap texttrue,
strokeradius of outline to render around the text- will be rendered in white. useful to contrast text against a background.0,
colorcolor to render text- overrides font's natural color. playdate.graphics.kColorBlack or kColorWhite.nil (use defualt font color)

playout.text:layout(context)

Computes the layout and dimensions of renderered text. Returns a playout.geometry.rect with the computed size. Usually indirectly called by playout.tree:layout.

playout.text:draw(rect)

Renders text into the provided playout.geometry.rect. Usually called indirectly by playout.tree:draw.

Properties

Changing properties will require re-running layout and draw to see the changes.

playout.text.text

Value of text string to render. changing this will likely require re-computing layout.

playout.text.properties

Table of properties, provided via initial creation.

playout.text.parent

Reference to a parent box, if any. set by appendChild, insertChild, or playout.tree. If children were changed directly via .children, their parent will not be set. read only.

playout.text.style

See Style Reuse.

playout.image

Allows for the incorporation of playdate.graphics.image into a layout.

Methods

playout.image.new(image, [properties])

Creates a new playout.image. Takes a playdate.graphics.image and an optional table of properties.

image nodes are sized to the width and height of their corresponding playdate.graphics.image, which is used in layout.

Returns a playout.image.

playout.text:layout(context)

Calculates a `play

playout.text:draw(rect)

Properties

playout.text.parent

Reference to a parent box, if any. set by appendChild, insertChild, or playout.tree. If children were changed directly via .children, their parent will not be set. Read only.

playout.tree

Structure for creating/accessing a tree of playout nodes. This is the recommended way to create, layout, and draw layouts.

Methods

playout.tree.new([root, [options])

Create a new playout.tree. Takes root, the top-level note of the tree (a box, text, or image), as well as a table of options.

Supported options:

optiondescriptiondefault
useCacheWhether or not to cache nodes looked up using tree:get(id). Makes subsequent lookups faster.true

playout.tree:layout()

Compute the layout of all children recursively, starting at root.

playout.tree.draw()

Returns a playdate.graphics.image containing the rendered tree. Will run tree:layout if it has not yet been run. To save on memory, this method will store and re-use the same image for subsequent re-renders (at tree.img), provided the computed layout dimensions of the tree haven't changed. Will automatically update an associated sprite if created with playout.tree:asSprite

playout.tree:asSprite()

Creates a new playdate.graphics.sprite, draws the tree into the sprite, and returns the sprite. Future calls to tree:draw will automatically update the sprite's image.

playout.tree:get(id)

Find a node in the tree based on its properties.id. Will recursively walk the tree to find the node. Returns the first node with matching id, or nil if no match was found. If tree.useCache is true, subsequent lookups will skip walking the tree.

playout.tree:computeTabIndex()

Computes a sequential list of nodes in the tree which have the tabIndex property set. Higher tabIndex values will be sorted later in the list. Useful for interactivity and menuing. The computed list will be store in the playout.tree.tabIndex property, which is nil until this method is called.

Properties

playout.tree.root

The top node of the layout tree.

playout.tree.tabIndex

An ordered list of nodes, sorted by their tabIndex property. Useful for interactivity and menuing. Will be nil until playout.tree:computeTabIndex() is called.

playout.tree.rect

A playdate.geometry.rect representing the dimensions of the tree after the last call to playout.tree:layout()

playout.tree.img

A playdate.graphics.image containing the latest results of calling playout.tree:draw()

playout.tree.sprite

A playout.graphics.sprite, populated after calling playout.tree:asSprite()

Utilities and Constants

Alignment

Used for hAlign and vAlign properties:

playout.kAlignStart

Children are aligned to the start of the box (left for hAlign, top for vAlign).

playout.kAlignCenter

Children are aligned to the center of the box (rounded down in the case of an odd width).

playout.kAlignEnd

Children are aligned to the end of the box (right for hAlign, bottom for vAlign).

playout.kAlignStretch

Resizes children to fill the available remaining space.

Only valid for off-axis alignment. If direction is vertical, valid for hAlign, if directon is horizontal, valid for vAlign. When used in selfAlign, always refers to the off-axis direction.

Anchoring

playout.getRectAnchor(r, anchor)

Returns a playdate.geometry.point for a given anchor position on the the provided playdate.geometry.rect:

playout.kAnchorTopLeft
playout.kAnchorTopCenter
playout.kAnchorTopRight
playout.kAnchorCenterLeft
playout.kAnchorCenter
playout.kAnchorCenterRight
playout.kAnchorBottomLeft
playout.kAnchorBottomCenter
playout.kAnchorBottomRight

Direction

Used for specifying the direction of box layout, horizontal or vertical:

playout.kDirectionVertical
playout.kDirectionHorizontal

Styling

All node types (box, image, and text) can take an optional style property. This is a table of properties that will override any properties provided at creation or default values. Can be used to define repeatable common collections of properties.

Example

local button = {
  padding = 4,
  border = 2,
  borderRadius = 4,
  shadow = 2
}

local options = playout.tree.new(
  playout.box.new({
    direction = playout.kDirectionHorizontal,
    spacing = 8
  }, {
    playout.box.new({ style = button, tabIndex = 1 }, { playout.text.new("Cancel") }),
    playout.box.new({ style = button, tabIndex = 2 }, { playout.text.new("Okay") }),
  })
)
1.0.1

11 months ago

1.0.0

11 months ago