Skip to content

Element Layout

Shane Brinkman-Davis edited this page Dec 27, 2016 · 42 revisions

Before you continue!

Be sure to read and understand Element Geometry.

Notes:

  • Units are always 'points' (pts). On normal screens, 1pt == 1pixel. On Apple Retina screens, 1pt == 2pixels. On other devices such as Android, ratios can be 1:2.5, 1:3 and other combinations.
  • The examples below are using Art.React notation. In pure Art.Engine: new Element(). In Art.React: Element(). In Art.React, Components and VirtualElements are Factories, not classes, so you don't need a 'new'.

TODO

This page needs diagrams! But the basics are here.

Definition: Layout

  • Geometry: Each element's geometry has a set of current values - its "current geometry." You can access these values as follows:
    • element.currentLocation
    • element.currentSize
    • NOTE: These values cannot be set directly.
  • Layout: An element's layout describes how its geometry should be computed, and updated based on its parent's size and the combined size of its children. You can read and write an elements layout as the following properties:
    • element.location
    • element.size

Layout Property Examples

# elements with location: 0 and size == parent.size
# (these are the default values for location and size)
Element
Element size: ps: 1
Element location: 0, size: ps: 1
Element size: ww: 1, hh: 1
Element
  location: x: 0, y: 0
  size: ww: 1, hh: 1

# element centered within their parent's area and width == height == 250
Element
  axis: "centerCenter"
  location: ps: .5
  size: 250

Element
  axis: "centerCenter"
  layout: xw: .5, yh: .5
  size: w: 250, h: 250

# element with location: point(10, 20) and size: point(30, 40)
Element
  location: point 10, 20
  size:     point 30, 40

Element
  location: x: 10, y: 20
  size:     w: 30, y: 40

# element which resizes with children
Element size: cs: 1
Element size: wcw: 1, hch: 1

PointLayout: Legal Values for location and size properties

Size and Location are both PointLayout properties. This means they generate both x and y values. They can be initialized as a:

  • constant layout with fixed values
  • dynamic layout expressed as an aribtrary function of parent-size and children-size
  • dynamic layout expressed as a set of options

Constant Layout: Points and Numbers

Constant layout values can be anything that is not a function or an object that is legal for an Atomic.Point constructor:

Element size: 123           # x = y = 123
Element size: point 1, 2    # x = 1, y = 2
Element size: [1, 2]        # x = 1, y = 2
Element size: "centerRight" # x = 1, y = .5 (named point)
Element size: "1, 2"        # x = 1, y = 2

Dynamic Layout: Functions

Element
  location: (parentSize)               -> Point or Number
  size:     (parentSize, childrenSize) -> Point or Number

Ultimately, layout is an arbitrary function based on parentSize and childrenSize returning a point. To take full advantage of this power, you can use the functional forms above.

Dynamic Layout: Declarative

However, most the time, element layout can be expressed more simply using the Declarative forms:

currentLocation.x layout

# layout.x is a function
Element
  location:           # currentLocation.x = layout.x parentSize
    x:      (parentSize) -> Number

# layout.x is not a function
Element
  location:           # currentLocation.x =
    x:      a         #   layout.x
    xw:     b         #   + layout.xw * parentSize.width
    plus:   c         #   + layout.plus
    ps:     d         #   + layout.ps * parentSize.width

# a, b, c, d are numbers [default = 0]

currentLocation.y layout

# layout.y is a function
Element
  location:           # currentLocation.y = layout.y parentSize
    y:      (parentSize) -> Number

# layout.y is not a function
Element
  location:           # currentLocation.y =
    y:      a         #   layout.y
    yh:     b         #   + layout.yh * parentSize.height
    plus:   c         #   + layout.plus
    ps:     d         #   + layout.ps * parentSize.height

# a, b, c, d are numbers [default = 0]

currentSize.width layout

# layout.w is a function
Element
  size:               # currentSize.width = size.w parentSize, childrenSize
    w:      (parentSize, childrenSize) -> Number

# layout.w is not a function
Element
  size:               # currentSize.width =
    w:      a         # layout.w
    ww:     b         # + layout.ww * parentSize.width
    wcw:    c         # + layout.wcw * childrenSize.width
    plus:   d         # + layout.plus
    ps:     e         # + layout.ps * parentSize.width
    cs:     f         # + layout.cs * childrenSize.width

# a, b, c, d, e, f all default to 0

currentSize.height layout

# layout.h is a function
Element
  size:               # currentSize.height = size.h parentSize, childrenSize
    h:      (parentSize, childrenSize) -> Number

# layout.h is not a function
Element
  size:               # currentSize.height =
    h:      a         # layout.h
    hh:     b         # + layout.hh * parentSize.height
    hch:    c         # + layout.hch * childrenSize.height
    plus:   d         # + layout.plus
    ps:     e         # + layout.ps * parentSize.height
    cs:     f         # + layout.cs * childrenSize.height

# a, b, c, d, e, f all default to 0

Aliases

x: a, w: a, width:  a
y: b, h: b, height: b

xw: c, xpw: c, ww: c, wpw: c, xParentWidth:  c, widthParentWidth:   c
yh: d, yph: d, hh: d, hph: d, yParentHeight: c, heightParentHeight: c

wcw: e, widthChildrenWidth:   e
hch: e, heightChildrenHeight: e

Cross-Factors & their Aliases (Rarely used)

xh: c, xph: c, wh: c, wph: c  # + layout.xh * parentSize.height
yw: d, ypw: d, hw: d, hpw: d  # + layout.yw * parentSize.width

wch: e                        # + layout.xch * childrenSize.height
hcw: e                        # + layout.ycw * childrenSize.width

max

The max option allows you to set a maximum x/width or y/height or both. Max can be any legal layout value listed above. Bellow is a common example setting an upper bound on the width of a TextElement to the width of its parent.

TODO: more detailed example

TextElement text: someLongText, size: cs: 1, max: ww: 1

childrenLayout and inFlow Properties

In addition to the layout property, there are two other important layout-related properties:

  • childrenLayout: options: ["flow", "column", "row"], default: null
  • inFlow: options: [true, false], default: true

If an element's childrenLayout is set to one of the "flow" options then all of its children with inFlow == true will have their locations set by flex and flow layouts.

Children with inFlow == false are laid out the same regardless if the parent element's childrenLayout is "flow" or not.

margin and padding

  • margin - only effects layout if the parent element has childrenLayout set. Margin guarantees at least the specified number of pts between this Element and any other Elements.
  • padding - padding only effects the layout of children. Children elements of a parent with padding see a smaller parent layout area.

Margin and padding be any value an Art.Atomic.Perimeter object accepts or functions taking (parentSize, childrenSize) and returning any value Art.Atomic.Perimeter accepts

Element
  padding: 
    h: a, horizontal: a # set left and right
    v: b, vertical:   b # set top and bottom
    l: c, left:       c
    r: d, right:      d
    t: e, top:        e
    b: f, bottom:     f

Clone this wiki locally