Layout files contain xml data. Instead of using Android's xml layout format (which is incredibly
complex) we created our own simpler format. With it, the goal is to be able to easily and quickly
build structures that look very similar to a real device.

A layout file must have a "screen" element as the root node. All other nodes are of the type "node"
or "include" (explained further down). All the nodes have various attributes that control their
appearances. Without any attributes, a layout file can look something like this:

<?xml version="1.0" encoding="UTF-8"?>
<screen>
  <node>
    <node/>
  </node>
  <include/>
</screen>

Of course, attributes are required for a layout file to be valid.
There are three main groups of attribute that nodes can have.

=======================
    Misc
=======================
All of these are optional.

    id - required if the node is to be found and modified from code
    background - background resource identifier. Should either be identifiers for drawable or color
                 resources (for example "@com.sonyericsson.home:drawable/home_bg"). You can also use
                 color constants in the following formats; "#RGB" & "#AARRGGBB".
    backgroundTint - color resource identifier or color constant. Used to tint the image you set
                     with the background attribute. If you set no backgorund, or if the background
                     is a color, this attribute does nothing.
    useContentBounds - Nine-patches can contain content padding. However, this is not always
                     applied as you might expect in Android. Also, previews often list elements by
                     organizing them as parents/children. Doing this while applying content bounds
                     can mess up the positioning for the children. For this reason,
                     nine-patch content bounds are disabled by default. Set this property to true
                     and content bounds will be used when positioning child nodes.
    rotation - the rotation of the node in degrees. Can for example be "45" or
               "@dimen/node_rotation".
    activity - can be set on a screen node to declare which activity this preview represents on a
               device. Declaring an activity is optional, but if you do declare one then you can
               use attribute references in your previews.
    style - can be set on any node in the hierarchy. The value should be a style identifier, for
            example "@android:style/Theme.Material.Light.DarkActionBar". Declaring this will insert
            the style *first* into the current style chain for this node and all child nodes. This
            attribute is ignored on the <screen> node if you specify the "activity" attribute.

    text - The text to be drawn in the node
    fontName - The name of the font. Can be "roboto-thin" (default), "roboto-black", "roboto-light",
      "roboto-regular" or "roboto-condensed-regular".
    textSize - Text size in pixels or % of node height. Default is 20 pixels.
    textColor - Text color. Same format as background color ("#RGB" & "#AARRGGBB")
    textAnchor - how the text should be placed within it's node. Specify this with one of the anchor
      values, e.g. topLeft, center, topRight, center etc. The value you select will make it so that
      the text's topLeft/center/etc is on the same position as the nodes topLeft/center/etc.
      So picking for example textAlign="left" will make the texts left edge align with the nodes
      left edge. Default value is center.
    textAlign - The alignment of the text to be used if the text spans multiple rows. Possible
      values are "left", "center", "right" (not case sensitive). Default value is center.
    textWrapX - The maximum width of the text before it must wrap to a new line. Default size is
      (nearly) infinite.
    textWrapY - The maximum height of the text before it must clip new lines. Default size is
      (nearly) infinite.

    clipChildren - disabled       # Do not clip anything and render children normally. This is
                                    the default value

                   inside         # clip inside our bounds and render the children normally.

                   inside_dst_out # clip inside our bounds and render the children using the
                                    PorterDuff rule "DstOut".

=======================
    Positioning
=======================

    positionX - can be pixels or %. E.g "100" & "50%"" are both valid values. % is relative to the
        parent's width (for positionX) or height (for positionY).
    positionY - same as for positionX.

    anchor - decides what part of the node you are setting the position for
        bottomLeft
        bottomRight
        topLeft
        topRight
        center
        top
        bottom
        right
        left

All these three attributes MUST be set by all nodes, except for the root node which implicitly gets
the values anchor="bottomLeft", positionX="0" and positionY="0".

A "graphical" representation or the anchor values can be seen below.

     topLeft________top_______ topRight
            |                 |
            |                 |
            |                 |
        left|      center     | right
            |                 |
            |                 |
            |_________________|
   bottomLeft      bottom      bottomRight


=======================
    Size
=======================

    width - the width. As with positionX & positionY, this can be both pixels and %. E.g. "100" &
            "50%" are both vald values. % is relative to the parent's size. E.g. setting "100%"
            means "make this node as large as it's parent".
    height - the height. Can be pixels or %, just as the width.


    scaling - aspect         # Default. aspect retains the images aspect ratio. If both width and
                               height is set then aspect will make the image as big as possible
                               within the bounds, but it won't necessary fill them.

            | stretch        # Stretch stretches the image to the bounds you set.
                               Must set BOTH width and height to use this.

            | maximize       # Makes the element AT LEAST as large as width and/or height specifies
                               while retaining aspect ratio. Leads to the image going outside it's
                               bounds if bounds aspect ratio != image aspect ratio.
                               Must set BOTH width and height to use this.

At least one of "width" or "height" must be set, except for the root node which will get it's width
and height from elsewhere. Setting a width or height on the root node has no effect.

Nodes with only one of width or height set calculate the non-set value the following way:

  1. Do I have a background image? If yes, calculate the non-set value from the image's aspect
     ratio.
  2. Copy the non-set value from the set value (makes the node square).

width and height can be set to "text". This will copy the width and/or height from however big the
text is. Note that the text attribute MUST be set to use this. Also note that you cannot set
height="text" and textSize="100%", as that would create a circular dependency (height dependent on
textsize, textsize dependent on height).


Example 1: Lets say height="50" and width isn't set. We have a background image that is 200 by
          100 pixels. Width will be set to "100" (= 50 * (200 / 100)).

Example 2: Lets say width="5" and height isn't set. We don't have a background image. Height
          will be set to "5".

Example 3: Lets say width="10", height="5", we have a background image that is 20 by 20 pixels.
           The scaling will determine the resulting size;

           With "aspect" the resulting size will be width="5" and height="5".
           With "stretch" the resulting size will be width="10" and height="5".
           With "maximize" the resulting size will be width="10" and height="10".


====================================================================================================
      Tips & tricks
====================================================================================================

                                        <include>

This is sort of an advanced feature which is required when doing bigger, more complex layouts.
Sometimes you will have several elements in a row  with nearly the same attributes. Or maybe you
want to create several versions of a layout that are almost identical, but with very slight
variations. Copy pasted code is ugly and hard to maintain, so instead you use the <include> feature.
With <include> you can define an external file which specifies a set of default attributes together
with variables that aren't set.

Lets say you have a set of nodes that share almost all attributes except for id and background.
What you do then is create an external file, let's call it node_template.xml with for example
the following content:


<?xml version="1.0" encoding="UTF-8"?>
<node
    id="$button_id"
    background="$button_background"

    anchor="center"
    positionX="10%"
    positionY="10%"

    scaling="stretch"

    width="50%"
    height="50%" />

Note the $ signs. $ means that this is an attribute that MUST be set when this file is included.

Now in your main layout file you can write

<include
    file="node_template.xml"
    button_id="node_id_1"
    button_background="@drawable/icon_1" />

<include
    file="node_template.xml"
    button_id="node_id_2"
    button_background="#0FF" />

Etc, as many times as you like!

You can have extra, optional attributes in your include statements as well; for example:

<include
    file="node_template.xml"
    button_id="node_id_2"
    button_background="@drawable/icon_2"
    text="Hello"/>

Since there is no "$text" value to map the text attribute to it will simply be set as an attribute
just as normal on the root node in the included file.

Include statements can have child nodes just as any other nodes. The children will be added to the
root node in the included file. The children can even be other include nodes. For example:

<include
    file="node_template.xml"
    button_id="node_id_1"
    button_background="@drawable/icon3">

    <include
        file="label_template.xml"
        label_text="I am a label" />

</include>

The external layout files may only have one root node. If more are present, only one of them is
picked (randomly), so keep it to one root node.

If you want to "disable" the include statement you can set "file" to "@null". This can be useful in
some situations explained in "Default include attributes.

Finally; these external layout files can have include statements in themselves! So you can include a
file that includes a file that includes a file that includes a file etc.

====================================================================================================

                                     Default include attributes

Sometimes most files that include something will have the same value, but one or two files will have
something special. Instead of having all files write out their values, you can have a default value
and still let that special file set their special value.

You do this with the "|" sign using the format:

    attribute="$key|defaultValue"

For example:

    <node
        text="$nodeText|Default label"
        [...] />

Or:

    <include
        file="$backgroundInclude|@null" />

Having @null as a default attribute in an include statment makes it as if the include statement
doesn't exist by default which can be useful in many cases.

If the including file doesn't specify your key, the text after the "|" sign will be used as
the value instead.

Just to summarize, there are three ways to set an attribute:

    attribute="value"
    attribute="$key"
    attribute="$key|defaultValue"

====================================================================================================

                                  Advanced text alignment

Sometimes you might want to align text more advanced than the textAnchor attribute seemingly allows.
What you then do is you create a child node that only contains the text. Then you position the
child so that the text gets your desired alignment. Here is an example of texts being aligned
in special locations relative the parent.

      <node
        {some attributes} >

        <node
          text="Outside topLeft"

          anchor="bottomLeft"
          positionX="0"
          positionY="100%"

          textAnchor="bottomLeft"

          textSize="100%"
          height="10%"
          width="text"/>

        <node
          text="Outside right"

          anchor="topLeft"
          positionX="100%"
          positionY="100%"

          textAnchor="topLeft"
          textSize="100%"
          height="10%"
          width="text"/>

        <node
          text="Below center"

          anchor="center"
          positionX="50%"
          positionY="20%"

          textAnchor="center"
          textSize="100%"
          height="10%"
          width="text"/>

      </node>




This will result in something like this:


  Outside topLeft
 |¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|Outside right
 |                                |
 |                                |
 |                                |
 |                                |
 |                                |
 |                                |
 |                                |
 |          Below center          |
 |________________________________|


====================================================================================================

                                  Fallback resources

Sometimes you can't be sure that the resources you want will be present. You might want a node to be
able to display a certain image, but in case that image doesn't exist you want to display another
image or a color instead. For this we have the "|" operator.

When the resource providers detect a "|" in your resource identifier, they split the identifier
around the "|" and try the resources one by one, only complaining if none of them could be found.

For example, you could have the following:

    background="@drawable/icon_v2|@drawable/icon_v1|#F00"

This will be split into:

   1: @drawable/icon_v2
   2: @drawable/icon_v1
   3: #F00

The resources will be queried one by one until one succeeds. If icon_v2 exists, that will be used.
If it doesn't exist, it will try to use icon_v1. If that doesn't exist either, it will try to use
"#F00" which will always succeed since it is a constant (red color).

====================================================================================================

                                  Known limitations

It is quite possible to create a layout file that crashes the program when loaded. The node builder
and resource provider will try to give as detailed error descriptions as possible, but there are
cases which aren't detected and handled properly that you should be aware of.

As mentioned earlier in the document, the following combinations of attributes are illegal:

    height="text"
    textSize="100%"

This creates a circular dependency between the text size and node height. The node builder detects
this and informs you of the error. The node builder will NOT, however, detect the following:

    height="text"
    textSize="eval(@special/this.height)"

This also creates a circular dependency, but it is much harder to detect at runtime since the eval
statement can make references to other dimension resources or nodes with specific identifiers that
may or may not end up referencing the height of the current node. This type of error should only
ever occur during development (the end users don't write layout files). Because of this, it isn't
really worth spending time to create a proper error message here. Instead, when you see a
StackOverflowError you know that you probably have a circular dependency like the example above
somewhere in your program.

This type of error isn't limited to text sizes. You can have something like this as well:

    <color name="someColor">@color/otherColor</color>
    <color name="otherColor">@color/someColor</color>

When the previewer tries to resolve either of the color resources it will go in an endless loop.
The program doesn't detect the loop, but instead crashes with a StackOverflowError.
