# Factory Func Example

An example of using a factory function to generate constraints.

This example shows how a function can be used as a delegate for generating the list of layout constraints. This mode of constraint generation is useful when the children of a container change dynamically at runtime. The factory will be invoked automatically whenever the internal layout engine determines that a relayout is necessary.

Tip

To see this example in action, download it from `factory_func` and run:

    $ enaml-run factory_func.enaml

## Screenshot

## Example Enaml Code

    #------------------------------------------------------------------------------
    # Copyright (c) 2014-2024,, Nucleic Development Team.
    #
    # Distributed under the terms of the Modified BSD License.
    #
    # The full license is in the file LICENSE, distributed with this software.
    #------------------------------------------------------------------------------
    """ An example of using a factory function to generate constraints.

    This example shows how a function can be used as a delegate for generating
    the list of layout constraints. This mode of constraint generation is useful
    when the children of a container change dynamically at runtime. The factory
    will be invoked automatically whenever the internal layout engine determines
    that a relayout is necessary.

    << autodoc-me >>
    """
    from itertools import zip_longest

    from enaml.core.api import Include
    from enaml.layout.api import align, grid, factory
    from enaml.widgets.api import Window, Container, Form, Field, Label, SpinBox

    def generate_grid(container, num_cols):
        """ Generate grid constraints with given number of columns.

        """
        rows = []
        widgets = container.visible_widgets()
        row_iters = (iter(widgets),) * num_cols
        rows = list(zip_longest(*row_iters))
        return [grid(*rows), align('width', *widgets)]

    enamldef Main(Window):
        title = 'Factory Helper'
        Container:
            padding = 0
            Form:
                Label:
                    text = 'Widget Count'
                SpinBox: w_count:
                    value = 4
                Label:
                    text = 'Column Count'
                SpinBox: c_count:
                    value = 2
                    minimum = 1
                    maximum = 5
            Container:
                # The << operator is only needed for the subscription to
                # the column count. The factory is automatically invoked
                # whenever the number of children of the container change.
                constraints << [factory(generate_grid, c_count.value)]
                Include:
                    objects << [Field(text=str(i)) for i in range(w_count.value)]