Text library blobs Files consist of a list of imports followed by a list of widget declarations. Imports Imports have this form: import library.name; Widget declarations To declare a widget named A in terms of a widget B, the following form is used: A = B(); If the widget A is to be stateful, a map is inserted before the equals sign: A { } = B(); The map describes the default values of the state. For example, a button might have a "down" state, which is initially false: Button { down: false } = Container(); References The various kinds of references all have the same basic pattern, a prefix followed by period-separated identifiers, strings, or integers. Identifiers and strings are used to index into maps, and integers are used to index into lists. For example, "foo.2.fruit" would reference the key with the value "Kiwi" in the following structure: { foo: [ { fruit: "Apple" }, { fruit: "Banana" }, { fruit: "Kiwi" }, ], bar: [ ], } In text files, references to a widget's arguments use "args" as the first component: args.foo.bar References to the data model use use "data" as the first component: data.foo.bar References to state use "state" as the first component: state.foo.bar Finally, references to loop variables use the identifier specified in the loop as the first component: ident.foo.bar Loops The syntax for a loop uses the following form: ...for ident in list: template ...where "ident" is the identifier to bind to each value in the list, "list" is some value that evaluates to a list, and "template" is a value that is to be evaluated for each item in "list". This loop syntax is only valid inside lists. Switches The syntax for a switch uses the following form: switch value { case1: template1, case2: template2, case3: template3, default: templateD, } ...where "value" is the control value that will be compared to each case, the "caseX" values are the values to which the control value is compared, "templateX" are the templates to use, and "templateD" is the default template to use if none of the cases can be met. Any number of cases can be specified; the template of the first one that exactly matches the given control value is the one that is used. The default entry is optional. If no value matches and there is no default, the switch evaluates to the "missing" value (null). Event handlers There are two kinds of event handlers. Signalling event handlers have this form: event "..." { } ...where the string is the name of the event and the map is the data to send with the event. State-setting handlers have this form: set state.foo.bar = value ...where "state.foo.bar" is a state reference as described above, and "value" is the value to assign to that state.