The layout engine uses a JSON configuration file that requires a basic structure like this:
layout.json
{
"widgets": []
}
The 'widgets' property is an array that holds all of the widgets for the layout engine to render. The available widgets types are: anchor, text, weather. You're free to use any of these but the most likely widget you will start with is the anchor.
Each of the widgets is a JSON object, it's type is specified by the 'type' property. For example adding an anchor widget would look like this...
layout.json
{
"widgets": [
{
"type": "anchor",
"anchor": [0, 0],
"children: []
}
]
}
Screen Coordinate System
All coordinates are defined as standard 2D Cartesian values with the top-left being treated as (0,0) and bottom-right as (width, height).
Anchor/Origin Coordinates
There are a number of widgets that make use of an origin or anchor property. This property is specified as a 2D Cartesian coordinate that is clamped to 2x2 pixels in size. This means it has values of either 0 or 1 for each of its axes. These properties define a corner of the widget/screen. The diagram below shows this...
Even though the value for each axis is either a 0 or a 1, the value of 1 actually means the width (for the x-axis) and the height (for the y-axis). From that, a value of (1,1) would define the bottom-right corner.
Widget Transformation
A number of widgets define the 'transform' property. This allows a widget to be transformed in 2D space. There are the following properties defined for a transform:
- origin : two-integer array specifying the transformation origin (x,y), similar to Anchor 'anchor'
- offset : two-integer array specifying the offset in pixels relative to the origin (x, y)
- rotate : degrees rotation around the origin point
- showBounds : whether to show the drawing boundary box or not
The origin is very important as that is the point around which both the translation and rotation are done. The translation is performed first, then the rotation is performed around the origin at the new (x,y) location. The translation value will not affect how a rotation is performed i.e. they do not stack.
Anchor Widget
By itself this widget does not display anything, but it is used to affect how its child widgets are displayed. The purpose of this widget is to anchor its children to one of the screen corners.
Properties:
- anchor : two-integer array specifying which side to anchor along an axis (x,y)
- children : list of child widgets
The 'children' property is an array of widgets that the anchor is to display relative to its position. This should only contain the text and weather widgets.
Examples
I will not go into specifics of the text or weather widgets as this article is about how to use the layout system, so for the examples below I'll be using a very simple text widget that displays the text "Hello World!". It's going to be configured as follows:
layout.json
{
"type": "text",
"text" : {
"data": "Hello World!",
"colour": [255,0,0],
"size": 20
}
}
If you want to learn more about the text and weather widgets, see the README.md.
Lets start with an example showing the text in the top-left corner...
layout.json
{
"widgets": [
{
"type": "anchor",
"anchor": [0, 0],
"children": [
{
"type": "text",
"transform": {
"origin": [0, 0],
"offset": [0, 0],
"showBounds": "true"
},
"text" : {
"data": "Hello World",
"colour": [255,0,0],
"size": 20
}
}
]
}
]
}
The above will render the following (showing just the relevant part of the screen)...
To move the text to (40,40) the offset is changed to:
layout.json
"offset": [40, 40]
Note the bounding box shows the origin location as a circle.
Now if we change the origin to [1,0] the result becomes...
The widget's rightmost corner is the part that is used to translate relative to, so only the last 40 pixels of the text are visible on screen now.
Now we can add a rotation of -90 degrees like so:
layout.json
"rotate": -90
This swivels the text back on screen, in a vertical position.
If we now change the anchor to [0,1] i.e. bottom-left corner and reset the rest of the widget properties i.e. the offset to [0,0] and rotation to 0, and the origin back to [0,0] the widget completely disappears...
There is a hint of the widget anchor in the bottom-left corner however. Why is the text widget not visible though? That's because its origin is placing its top-left corner in the bottom-left part of the screen via the anchor. This renders the text 'below' the screen. To get the text back on screen, its origin must be changed to the match the anchor ie. we change the origin to [0,1]...
So by manipulating the anchor and the origin of the widget, text can be snapped to any corner on screen. The offset and rotation then further influence how the text is moved or spun around relative to that snapped-to location. The possibilities are endless!
Hopefully that explains how the layout engine works in more detail.
-i