Skip to content
enderger edited this page Jun 15, 2020 · 2 revisions

Layout DSL

The layout DSL (Domain Specific Language) is designed to help with common use-case layout definitions. Here is an example:

import nimx / [ window, button, layout ]

let
   w = newWindow(newRect(50,50,400,200))
   margin = 5.0

w.makeLayout:
   - Button:
      leading == super.leading + margin
      trailing == super.trailing - margin
      top == super.top + margin
      bottom == super.bottom - margin

      title: "Hello"
      onAction:
         echo "Hello, world!"

The makeLayout macro accepts the View as a first argument. The view is where the layout should happen. The second argument is the body of the DSL. It has the following syntax:

DSL ::= ViewConfiguration

ViewConfiguration ::= ViewConfigurationStatement*

ViewConfigurationStatement ::=
      "discard"
    | SubviewDefinition
    | PropertyDefinition
    | ConstraintDefinition

SubviewDefinition ::= "-" ( ViewType | ViewCreationExpression ) ( "as" Identifier )? ":" ViewConfiguration
PropertyDefinition ::= PropertyName ":" PropertyValue
ConstraintDefinition ::= ConstraintExpression (ConstraintPriority)?
  • In the example above, the - Button: and everything that follows is the SubviewDefinition. Button is the ViewType. Note that the types have to be valid symbols in the scope of the layout definition, that's why the sample code imports button.

  • title: "Hello" is the property definiton of the button. If the button was bound to a variable myButton, this would be equivalent to myButton.title = "Hello".

  • onAction: ... is also a property, but with a special rule: Properties starting with "on" and with an uppercased third letter are treated as callback properties. So this would expand to roughly

    myButton.onAction = proc() =
       echo "Hello, world!"

    If your callback takes arguments or returns something, you can use the do-notation:

    - MyControl:
       onSomeEvent do(e: EventData) -> EventDataResult:
          echo "hi"
  • leading == super + margin is a constraint definition, consisting of constraint expression, and default priority. Constraint expression should always be one of the following comparison expressions: <=, ==, or >=. Constraint expressions can refer to the following "variables": width, height, left, right, x, y, top, bottom, leading, trailing, centerX, centerY, origin, center, size.

Examples

  • mySubView should completely fill the mainView:
mainView.makeLayout:
 - View as mySubView:
    center == super.center
    width == 20
    height == 20
Clone this wiki locally