## Expression Language

In PaintCode, you can define variables that depend on other variables using our simple Expression Language. It supports many of the mathematic and logical functions and operators that most programmers expect. The syntax is simple, a subset of both C and JavaScript.

Just create a new variable of kind Expression and write an expression into the text view. Value of the new variable will be calculated and updated automatically.

After you export your PaintCode document, these variable expressions are transformed into the programming language you chose (Objective-C, Swift, C#, JavaScript and Java). The calculations and dynamic relationships between variables that they define will keep working in the exported code.

## Types of variables

### Numbers

All numbers in PaintCode are floating points. These expressions return numbers:

5

5 * 4 + 3 * 2

You can easily reference other variables in expressions. The language also has some built-in functions you can call:

width * (4 - offset)

sin(2.7 / PI * 180)

sqrt(width * width + heigt * height)

### Texts

Text variables are strings of unlimited length. You can use either double quote " or single quote ' as text qualifiers:

"This is text!"

'This is also text, now using single quotes.'

Texts can be concatenated using the + operator. Number can be converted to text using the stringFromNumber(x) function.

"angle: " + stringFromNumber(180)

You can use the dot-notation to access the length (number of letters) of the text. This returns a Number.

"Hello".length

### Booleans

Boolean variables are used to represent logical values - true and false. Alternative, you can also use (YES, yes, NO, no) constants.

The result of comparisons are always booleans. Examples of expressions that return booleans:

true

3 > 2

"hello" != "world"

mousePosition.x >= activeRect.x && mousePosition.y >= activeRect.y && mousePosition.x <= activeRect.x + activeRect.width && mousePosition.y <= activeRect.y + activeRect.height

You can also use the ternary ?: operator to return one of two values, depending on the value of the first argument. The second and the third arguments have to be of the same type (in this case, texts):

isValid ? "Valid" : "Invalid"

### Point

Create new point using the makePoint(x, y) function:

makePoint(10, 20)

Let's assume you have a point variable (called myPosition) and want to use the x-coordinate of the point in your expression. Use the dot notation like this:

myPosition.x + 100

Here's how you can compute the point in the middle between two points called "positionA" and "positionB":

makePoint((positionA.x + positionB.x) / 2, (positionA.y + positionB.y) / 2)

### Size

Size is similar to point. It also consists of two numbers, but they are called width and height. Its main purpose is to represent size of a rectangle.

makeSize(10, 20)

Let's assume you have defined a size variable called *defaultSize* and a numeric variable *zoom*. Now you want a new size with enlarged width by factor *zoom*:

makeSize(zoom * defaultSize.width, defaultSize.height)

### Rectangle

Rectangle variable consists of four numbers: x, y, width, height. There is a function makeRect(x, y, width, height) for creating a rectangle value. Width and height represent size of the rectangle and (x, y) is its origin.

makeRect(0, 0, 640, 1136)

Let's assume you have a rect called iPhoneBounds. Not only can you easily access the individual components (x, y, width, height), you can also get the size or origin of the rectangle:

iphoneBounds.size

These two expressions are equivalent:

iphoneBounds.origin.x + iphoneBounds.size.width

iphoneBounds.x + iphoneBounds.width

### Color

Color is represented by four numbers: red component, green component, blue component and alpha component. Each component is from interval 1. Create colors using the makeColor(r, g, b, a) function. The following expression returns solid yellow color:

makeColor(1, 1, 0, 1)

Colors defined in your library can also be used in expressions (for example, to return one of two colors based on whether a button is pressed). However, be careful when referencing colors (and other library items such as gradients and shadows) in your expressions. They can have arbitrary names, but names of variables are restricted:

- only characters from english alphabet, numbers and underscore are allowed
- only lower case character at the beginning of the variable name

Names of your colors may contain spaces, accents and symbols (e.g. "Dialog Background Color"), but when referring to them from script, use "sanitized" form as in this example:

Some examples of original and sanitized library item identifiers:

original item name | sanitized item name |
---|---|

myColor | myColor |

Bézier Color | bezierColor |

button-background | buttonbackground |

button_background 1 | button_background1 |

$a%#^(4)@ | a4 |

Extrémité | extremite |

### Gradient

To create a two step gradient, use the makeGradient(color1, color2) function. The red-to-transparent gradient can be defined as follows:

makeGradient(makeColor(1, 0, 0, 1), makeColor(1, 0, 0, 0))

Or, if you already have the two colors, you can just do this:

makeGradient(solidRedColor, transparentRedColor)

### Shadow

To create a shadow, use the makeShadow(color, offsetX, offsetY, blur) function.

makeShadow(solidRedColor, 5, 5, 3)

## Operators

Operators arranged by their priorities:

operator | type | result |
---|---|---|

!b | boolean | logical negation of b |

x * y | numbers | product of numbers x and y |

x / y | numbers | quotient of numbers x and y |

x % y | numbers | remainder after performing division of x and y; modulus |

m + n | texts | concatenation of the texts m and n |

x + y | numbers | sum of numbers x and y |

x - y | numbers | difference of x and y |

x > y | numbers | true if x is greater than y, false otherwise |

x >= y | numbers | true if x is greater than or equal to y, false otherwise |

x < y | numbers | true if x is less than y, false otherwise |

x <= y | numbers | true if x is less than or equal to y, false otherwise |

a == b | same type | true if a is equal to b, false otherwise |

a != b | same type | true if a is not equal to b, false otherwise |

a && b | booleans | true if a and b both true, false otherwise |

a || b | booleans | false if a and b both false, true otherwise |

b ? x : y | b - boolean x, y - same |
if b is true, result is x, otherwise result is y |

## Constants

- boolean constants: yes, no, true, false, YES, NO
- numeric constant: PI
- color constant: MISSING_COLOR
- gradient constant: MISSING_GRADIENT
- shadow constant: MISSING_SHADOW
- image constant: MISSING_IMAGE

## Basic Math Functions

### floor(x)

returns x rounded downwards

### ceil(x)

returns x rounded upwards

### round(x)

returns x rounded to nearest integer

### frac(x)

returns the fractional part of x

### sqrt(x)

returns the square root of x

### abs(x)

returns the absolute value of x

### min(x, y)

returns the smaller of the two parameters

### max(x, y)

returns the larger of the two parameters

### pow(x, y)

returns the x raised to the power of y

### log(x)

returns the natural base logarithm of a number

### log2(x)

returns the base 2 logarithm of a number

### log10(x)

returns the base 10 logarithm of a number

## Goniometric Functions

### sin(a), cos(a), tan(a)

goniometric functions.

Note: parameter a should be in degrees

### atan2(y, x)

arc tangent in degrees of y/x based on the signs of both values to determine the correct quadrant

## Colors, gradients and shadows

### makeColor(r, g, b, a)

returns color with components r, g, b, a (red, green, blue, alpha). All parameters should be from interval 0..1

### makeGradient(c1, c2)

returns two step gradient with colors c1 and c2

### makeShadow(color, xOffset, yOffset, blurRadius)

returns shadow

## Other Functions

### makePoint(x, y)

returns point

### makeSize(width, height)

returns size

### makeRect(x, y, width, height)

returns rect with position of origin (x, y) and size (width, height)

### stringFromNumber(x)

converts number x to text