# Source code for enaml.widgets.stack

    #------------------------------------------------------------------------------
    # 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 Atom, Enum, Int, Range, Typed, ForwardTyped, set_default

    from enaml.core.declarative import d_, observe

    from .constraints_widget import ConstraintsWidget, ProxyConstraintsWidget
    from .stack_item import StackItem

    class Transition(Atom):
        """ An object representing an animated transition.

        Once a transition is created, it should be considered read-only.

        """
        #: The type of transition effect to use.
        type = Enum('slide', 'wipe', 'iris', 'fade', 'crossfade')

        #: The direction of the transition effect. Some transition types
        #: will ignore the direction if it doesn't apply to the effect.
        direction = Enum(
            'left_to_right', 'right_to_left', 'top_to_bottom', 'bottom_to_top'
        )

        #: The duration of the transition, in milliseconds.
        duration = Range(low=0, value=250)

    class ProxyStack(ProxyConstraintsWidget):
        """ The abstract definition of a proxy Stack object.

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

        def set_index(self, index):
            raise NotImplementedError

        def set_transition(self, transition):
            raise NotImplementedError

        def set_size_hint_mode(self, mode):
            raise NotImplementedError

    class Stack(ConstraintsWidget):
        """ A component which displays its children as a stack of widgets,
        only one of which is visible at a time.

        """
        #: The index of the visible widget in the stack. The widget itself
        #: does not provide a means to changing this index. That control
        #: must be supplied externally. If the given index falls outside of
        #: the range of stack items, no widget will be visible.
        index = d_(Int(0))

        #: The item transition to use when changing between stack items.
        transition = d_(Typed(Transition))

        #: The size hint mode for the stack. The default is 'union' and
        #: means that the size hint of the stack is the union of all the
        #: stack item size hints. 'current' means the size hint of the
        #: stack will be the size hint of the current stack item.
        size_hint_mode = d_(Enum('union', 'current'))

        #: A Stack expands freely in height and width by default
        hug_width = set_default('ignore')
        hug_height = set_default('ignore')

        #: A reference to the ProxyStack widget.
        proxy = Typed(ProxyStack)

        def stack_items(self):
            """ Get the stack items defined on the stack

            """
            return [c for c in self.children if isinstance(c, StackItem)]

        #--------------------------------------------------------------------------
        # Observers
        #--------------------------------------------------------------------------
        @observe('index', 'transition', 'size_hint_mode')
        def _update_proxy(self, change):
            """ An observer which sends state change to the proxy.

            """
            # The superclass handler implementation is sufficient.
            super(Stack, self)._update_proxy(change)