- 
                Notifications
    
You must be signed in to change notification settings  - Fork 78
 
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 theSubviewDefinition.Buttonis theViewType. Note that the types have to be valid symbols in the scope of the layout definition, that's why the sample code importsbutton. - 
title: "Hello"is the property definiton of the button. If the button was bound to a variablemyButton, this would be equivalent tomyButton.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 roughlymyButton.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 + marginis 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. 
- 
mySubViewshould completely fill themainView: 
mainView.makeLayout:
 - View as mySubView:
    center == super.center
    width == 20
    height == 20- 
mySubViewshould be of size 20x20 and be centered within the mainView: 
mainView.makeLayout:
 - View as mySubView:
    center == super.center
    width == 20
    height == 20Note that there is a special word super in the above examples. This is a placeholder designating the superview of the currently defined view. There are other placeholders:
- 
self- The currently defined view - 
prev- The previous sibiling of the currently defined view - 
next- The next sibining of the currently defined view 
Note that the pattern of something == super.something is pretty common, so there is a special case to make it shorter:
mainView.makeLayout:
 - View:
    center == superThis works because the left side of the constraint consists of exactly one identifier which is treated as the subject. When super, self, prev, or next are met in the expression and it is not within the dot-expression, it is treated as a dot expression within the subject.
If the left side of the expression is not a single identifier, then there is no subject and thus such a shortcut would not work:
mainView.makeLayout:
   - View:
      width + 20 == super # Will not compile
      width + 20 == super.width # Will compile
      width == super - 20 # Will compile