# Source code for enaml.widgets.constraints_widget

    #------------------------------------------------------------------------------
    # Copyright (c) 2013-2025, Nucleic Development Team.
    #
    # Distributed under the terms of the Modified BSD License.
    #
    # The full license is in the file LICENSE, distributed with this software.
    #------------------------------------------------------------------------------
    from atom.api import List, ForwardTyped, Typed

    from enaml.core.declarative import d_, observe
    from enaml.layout.constrainable import ConstrainableMixin, PolicyEnum

    from .widget import Widget, ProxyWidget

    class ProxyConstraintsWidget(ProxyWidget):
        """ The abstract definition of a proxy ConstraintsWidget object.

        """
        #: A reference to the ConstraintsWidget declaration.
        declaration = ForwardTyped(lambda: ConstraintsWidget)

        def request_relayout(self):
            raise NotImplementedError

    class ConstraintsWidget(Widget, ConstrainableMixin):
        """ A Widget subclass which adds constraint information.

        A ConstraintsWidget is augmented with symbolic constraint variables
        which define a box model on the widget. This box model is used to
        declare constraints between this widget and other components which
        participate in constraints-based layout.

        Constraints are added to a widget by assigning a list to the
        'constraints' attribute. This list may contain raw Constraint
        objects, which are created by manipulating the symbolic constraint
        variables, or ConstraintHelper objects which generate Constraint
        objects on request.

        """
        #: The list of user-specified constraints or ConstraintHelpers.
        constraints = d_(List())

        # Redefine the policy enums as declarative members. The docs on
        # the ConstrainableMixin class provide their full explanation.
        hug_width = d_(PolicyEnum('strong'))
        hug_height = d_(PolicyEnum('strong'))
        resist_width = d_(PolicyEnum('strong'))
        resist_height = d_(PolicyEnum('strong'))
        limit_width = d_(PolicyEnum('ignore'))
        limit_height = d_(PolicyEnum('ignore'))

        #: A reference to the ProxyConstraintsWidget object.
        proxy = Typed(ProxyConstraintsWidget)

        #--------------------------------------------------------------------------
        # Observers
        #--------------------------------------------------------------------------
        @observe(
            'constraints', 'hug_width', 'hug_height', 'resist_width',
            'resist_height', 'limit_width', 'limit_height', 'visible')
        def _layout_invalidated(self, change):
            """ An observer which will relayout the proxy widget.

            """
            if change['type'] == 'update':
                self.request_relayout()

        #--------------------------------------------------------------------------
        # Public API
        #--------------------------------------------------------------------------

        def request_relayout(self):
            """ Request a relayout from the proxy widget.

            This will invoke the 'request_relayout' method on an active
            proxy. The proxy should collapse the requests as necessary.

            """
            if self.proxy_is_active:
                self.proxy.request_relayout()

        def when(self, switch):
            """ A method which returns `self` or None based on the truthness
            of the argument.

            This can be useful to easily turn off the effects of an object
            in constraints-based layout.

            Parameters
            ----------
            switch : bool
                A boolean which indicates whether this instance or None
                should be returned.

            Returns
            -------
            result : self or None
                If 'switch' is boolean True, self is returned. Otherwise,
                None is returned.

            """
            if switch:
                return self

        def layout_constraints(self):
            """ Get the constraints to use for this component's layout.

            This method may be overridden by subclasses as needed to create
            custom constraints. It will be called when the relayout request
            has been made by the layout engine. The default implementation
            will return the list of 'constraints' defined by the user.

            """
            return self.constraints