7.9 KiB
The .60
language reference
This page is work in progress as the language is not yet set in stones.
TODO
indicate things that are not yet implemented.
Comments
C-style comments are supported:
- line comments:
//
means everything to the end of the line is commented. - block comments:
/* .. */
(TODO, make possible to nest them)
.60
files
The basic idea is that the .60 files contains one or several components. These components consist of a bunch of elements that form a tree. Each declared component can be re-used as an element later. There are also a bunch of [builtin elements].
MyButton := Rectangle {
// ...
}
export MyApp := Window {
MyButton {
text: "hello";
}
MyButton {
text: "world";
}
}
Here, both MyButton
and MyApp
are components.
One can give name to the elements using the :=
syntax in front an element:
//...
MyApp := Window {
hello := MyButton {
text: "hello";
}
world := MyButton {
text: "world";
}
}
The outermost element of a component is always accessible under the name root
.
The current element can be referred as self
.
The parent element can be referred as parent
.
These names are reserved and cannot be used as an element name.
Properties
The elements can have properties
Example := Rectangle {
// Simple expression: ends with a semi colon
width: 42px;
// or a code block
height: { 42px }
}
You can declare properties. The properties declared at the top level of a component are public and can be accessed by the component using it as an element, or using the language bindings.
Properties are declared like so:
Example := Rectangle {
// declare a property of type int
property<int> my_property;
// declare a property with a default value
property<int> my_second_property: 42;
}
The value of properties are an expression (see later). You can access properties in these expression, and the bindings are automatically re-evaluated if any of the accessed properties change.
Example := Rectangle {
// declare a property of type int
property<int> my_property;
// This access the property
width: root.my_property * 20px;
}
If someone changes my_property
, the width will be updated automatically.
Types
int
float
:int
andfloat
are the types for the numbers, they correspond to the equivalent in the target language A number can end with '%', so for example30%
is the same as0.30
string
: Represent a utf8 encoded string. Strings are reference counted.color
: color literal follow more or less the CSS specslength
: the type for the x, y, width and height coordinate. This is an amount of physical pixels. To convert from an integer to a length unit, one can simply multiply by1px
. Or to convert from a length to a float, one can divide by1px
.logical_length
: correspond to literal like1lx
,1pt
,1in
,1mm
, or1cm
. It can be converted to and from length provided the binding is run in a context where there is an access to the pixel ratio.duration
: is a type for the duration of animation, it is represented by the amount of milisecond. But in the language they correspond to the number like1ms
or1s
easing
: follow more or less the CSS spec
Expressions
Basic arithmetic expression do what they do in most languages with the operator *
, +
, -
, /
Example := Rectangle {
x: 1 * 2 + 3 * 4; // same as (1 * 2) + (3 * 4)
}
Access properties with .
Example := Rectangle {
x: foo.x;
foo := Rectangle {
x: 42;
}
}
Strings are with duble quote: "foo"
.
(TODO: escaping, support using stuff like `hello {foo}`
)
Example := Text {
text: "hello";
}
Color literal use the CSS syntax:
Example := Rectangle {
color: blue;
property<color> c1: #ffaaff;
}
Array / Object
TODO
Signal
Example := Rectangle {
// declares a signal
signal hello;
area := TouchArea {
// sets a handler with `=>`
clicked => {
// emit the signal
root.hello()
}
}
}
TODO: add parameter to the signal
Repetition
The for
syntax
Example := Rectangle {
for person[index] in model: Button {
}
}
Animations
Simple animation that animates a property can be declared with animate
like so:
Example := Rectangle {
property<bool> pressed;
color: pressed ? blue : red;
animate color {
duration: 100ms;
}
}
This will aniate the color property for 100ms when it changes.
Animation can be configured with the following parameter:
duration
: the amount of time it takes for the animation to completeloop_count
: FIXMEeasing
: can belinear
,ease
,ease_in
,ease_out
,ease_in_out
,cubic_bezier(a, b, c, d)
as in CSS
It is also possible to animate sevaral properties with the same animation:
animate x, y { duration: 100ms; }
is the same as
animate x { duration: 100ms; }
animate y { duration: 100ms; }
States
The states
statement alow to declare states like so:
Example := Rectangle {
text := Text { text: "hello" }
property<bool> pressed;
property<bool> enabled;
states [
disabled when !enabled : {
color: gray; // same as root.color: gray;
text.color: white;
}
down when pressed : {
color: blue;
}
]
}
In that example, when the enabled
property is set to false, the disabled
state will be entered
This will change the color of the Rectangle and of the Text.
Transitions (TODO)
Complex animation can be declared on state transitions:
Example := Rectangle {
text := Text { text: "hello" }
property<bool> pressed;
property<bool> enabled;
states [
disabled when !enabled : {
color: gray; // same as root.color: gray;
text.color: white;
}
down when pressed : {
color: blue;
}
]
transitions [
to down {
animate color { duration: 300ms }
}
out disabled {
animate * { duration: 800ms }
}
]
}
Modules
Components declared in a .60 file can be shared with components in other .60 files, by means of exporting and importing them. By default, everything declared in a .60 file is private, but it can be made accessible from the outside using the export keyword:
ButtonHelper := Rectangle {
// ...
}
Button := Rectangle {
// ...
ButtonHelper {
// ...
}
}
export { Button }
In the above example, Button
is usable from other .60 files, but ButtonHelper
isn't.
It's also possible to change the name just for the purpose of exporting, without affecting its internal use:
Button := Rectangle {
// ...
}
export { Button as ColorButton }
In the above example, Button
is not accessible from the outside, but instead it is available under the name ColorButton
.
For convenience, a third way of exporting a component is to declare it exported right away:
export Button := Rectangle {
// ...
}
Similarly, components exported from other files can be accessed by importing them:
import { Button } from "./button.60";
App := Rectangle {
// ...
Button {
// ...
}
}
In the event that two files export a type under the same then, then you have the option of assigning a different name at import type:
import { Button } from "./button.60";
import { Button as CoolButton } from "../other_theme/button.60";
App := Rectangle {
// ...
CoolButton {} // from cool_button.60
Button {} // from button.60
}
Builtin elements
Rendered Items
Rectangle
Image
Path
TouchArea
Layouts
Window (TODO)
GridLayout
PathLayout
Flickable
...