U
    P’“eS2  ã                   @   s@   d Z dZddlmZ ddlmZ ddlmZ G dd„ deƒZdS )	aM  
Layout
======

Layouts are used to calculate and assign widget positions.

The :class:`Layout` class itself cannot be used directly.
You should use one of the following layout classes:

- Anchor layout: :class:`kivy.uix.anchorlayout.AnchorLayout`
- Box layout: :class:`kivy.uix.boxlayout.BoxLayout`
- Float layout: :class:`kivy.uix.floatlayout.FloatLayout`
- Grid layout: :class:`kivy.uix.gridlayout.GridLayout`
- Page Layout: :class:`kivy.uix.pagelayout.PageLayout`
- Relative layout: :class:`kivy.uix.relativelayout.RelativeLayout`
- Scatter layout: :class:`kivy.uix.scatterlayout.ScatterLayout`
- Stack layout: :class:`kivy.uix.stacklayout.StackLayout`


Understanding the `size_hint` Property in `Widget`
--------------------------------------------------

The :attr:`~kivy.uix.Widget.size_hint` is a tuple of values used by
layouts to manage the sizes of their children. It indicates the size
relative to the layout's size instead of an absolute size (in
pixels/points/cm/etc). The format is::

    widget.size_hint = (width_proportion, height_proportion)

The proportions are specified as floating point numbers in the range 0-1. For
example, 0.5 represents 50%, 1 represents 100%.

If you want a widget's width to be half of the parent's width and the
height to be identical to the parent's height, you would do::

    widget.size_hint = (0.5, 1.0)

If you don't want to use a size_hint for either the width or height, set the
value to None. For example, to make a widget that is 250px wide and 30%
of the parent's height, do::

    widget.size_hint = (None, 0.3)
    widget.width = 250

Being :class:`Kivy properties <kivy.properties>`, these can also be set via
constructor arguments::

    widget = Widget(size_hint=(None, 0.3), width=250)

.. versionchanged:: 1.4.1
    The `reposition_child` internal method (made public by mistake) has
    been removed.

)ÚLayouté    )ÚClock)ÚWidget)Úisclosec                       sL   e Zd ZdZdZ‡ fdd„Zdd„ Z‡ fdd„Z‡ fd	d
„Zdd„ Z	‡  Z
S )r   zoLayout interface class, used to implement every layout. See module
    documentation for more information.
    Nc                    sB   | j tkrtdƒ‚| jd kr,t | jd¡| _tt| ƒjf |Ž d S )NzIThe Layout class is abstract and                 cannot be used directly.éÿÿÿÿ)	Ú	__class__r   Ú	ExceptionÚ_trigger_layoutr   Zcreate_triggerÚ	do_layoutÚsuperÚ__init__)ÚselfÚkwargs©r   © ú3/tmp/pip-unpacked-wheel-xzebddm3/kivy/uix/layout.pyr   F   s
    

zLayout.__init__c                 G   s   t dƒ‚dS )aÍ  This function is called when a layout is called by a trigger.
        If you are writing a new Layout subclass, don't call this function
        directly but use :meth:`_trigger_layout` instead.

        The function is by default called *before* the next frame, therefore
        the layout isn't updated immediately. Anything depending on the
        positions of e.g. children should be scheduled for the next frame.

        .. versionadded:: 1.0.8
        z"Must be implemented in subclasses.N)ÚNotImplementedError)r   Úlargsr   r   r   r
   N   s    zLayout.do_layoutc                    sR   |j }|d| jƒ |d| jƒ |d| jƒ |d| jƒ tt| ƒj|f|ž|Ž d S ©NÚsizeZ	size_hintZsize_hint_maxZsize_hint_min)Úfbindr	   r   r   Ú
add_widget)r   ÚwidgetÚargsr   r   r   r   r   r   [   s    zLayout.add_widgetc                    sR   |j }|d| jƒ |d| jƒ |d| jƒ |d| jƒ tt| ƒj|f|ž|Ž d S r   )Úfunbindr	   r   r   Úremove_widget)r   r   r   r   r   r   r   r   r   c   s    zLayout.remove_widgetc           &         sª  |sdS |t |ƒ }||ks&t||ƒrntt||ƒƒD ]4\}\}	}
|	dkrJq4|
dk	r`|
| ||< q4d||< q4dS i }i }i }i }d }}|dd… }tt|||ƒƒD ]\}\}	}
}|	dkr¼q¢d}|
dk	r|
|9 }
|
|	 }|dkrô|
||< ||7 }nd||< || |
 ||< nd||< || ||< |dk	rr||9 }|	| }|dkrX|||< ||7 }nd||< |||  ||< nd||< |||  ||< ||kr¢td|ƒ||< ||kr¢td|ƒ||< q¢|| }t||ddrÖdS |dkrò|}|}d}|‰nx|dk rj|d9 }|}|}d}td	d
„ |D ƒƒ}tdd
„ |D ƒƒ}||krP|rLd| ndn|| ‰‡fdd„|D ƒ‰t t‡fdd
„|D ƒƒƒ‰ˆdk r |dksœt‚dS ‡‡fdd„| ¡ D ƒ‰ t	dd
„ |D ƒ‡ fdd„d}|d }|| }ˆ | }||| i}ˆ| }t
|ƒ} d}d| k r(|d }ˆ | }!d}"|"sL|| k rL|| k r||!kr|| }||| 7 }|ˆ| 7 }|| ||< ˆ | }!|d7 }q<|!}|"s,|| |ˆ  }#|#|! dkrÆ|| k rÆq,d}"t| ¡ ƒD ]b\}$}%|#|%ˆ|$ ˆ   dkrÖ||$= |||$ 8 }|ˆ|$ 8 }||%8 }||$  ||% 7  < d}"qÖ|s”q,q”q,|r¦|r^|sbt‚|| |ˆ  }#|D ].}||  ||#ˆ|  ˆ ||   7  < qvdS )a  (internal) Computes the appropriate (size) hint for all the
        widgets given (potential) min or max bounds on the widgets' size.
        The ``hint`` list is updated with appropriate sizes.

        It walks through the hints and for any widgets whose hint will result
        in violating min or max constraints, it fixes the hint. Any remaining
        or missing space after all the widgets are fixed get distributed
        to the widgets making them smaller or larger according to their
        size hint.

        This algorithms knows nothing about the widgets other than what is
        passed through the input params, so it's fairly generic for laying
        things out according to constraints using size hints.

        :Parameters:

            `sh_sum`: float
                The sum of the size hints (basically ``sum(size_hint)``).
            `available_space`: float
                The amount of pixels available for all the widgets
                whose size hint is not None. Cannot be zero.
            `min_bounded_size`: float
                The minimum amount of space required according to the
                `size_hint_min` of the widgets (basically
                ``sum(size_hint_min)``).
            `sh_min_vals`: list or iterable
                Items in the iterable are the size_hint_min for each widget.
                Can be None. The length should be the same as ``hint``
            `sh_max_vals`: list or iterable
                Items in the iterable are the size_hint_max for each widget.
                Can be None. The length should be the same as ``hint``
            `hint`: list
                A list whose size is the same as the length of ``sh_min_vals``
                and ``sh_min_vals`` whose each element is the corresponding
                size hint value of that element. This list is updated in place
                with correct size hints that ensure the constraints are not
                violated.

        :returns:
            Nothing. ``hint`` is updated in place.
        Ng        r   gVçž¯Ò<)Zabs_tolg      ð?gVçž¯Ò¼g      ð¿c                 s   s   | ]}|r|V  qd S ©Nr   ©Ú.0Úhr   r   r   Ú	<genexpr>ù   s      z1Layout.layout_hint_with_bounds.<locals>.<genexpr>c                 s   s   | ]}|d k	r|V  qd S r   r   r   r   r   r   r    ú   s      g       @c                    s    g | ]}|d krd nˆ | ‘qS r   r   r   )Úhint_topr   r   Ú
<listcomp>ü   s   ÿz2Layout.layout_hint_with_bounds.<locals>.<listcomp>c                 3   s   | ]}ˆ | V  qd S r   r   ©r   Úi)Úcontrib_proportionr   r   r      s     g•Ö&è.>c                    s"   i | ]\}}||ˆ| ˆ   “qS r   r   )r   r$   Úval)Úcontrib_prop_sumr%   r   r   Ú
<dictcomp>	  s   ÿ z2Layout.layout_hint_with_bounds.<locals>.<dictcomp>c                 s   s   | ]
}|V  qd S r   r   r#   r   r   r   r      s     c                    s   ˆ |  S r   r   )Úx)Úcontrib_heightr   r   Ú<lambda>  ó    z0Layout.layout_hint_with_bounds.<locals>.<lambda>)Úkeyé   FT)Úfloatr   Ú	enumerateÚzipÚmaxÚminÚsumÚAssertionErrorÚitemsÚsortedÚlenÚlist)&r   Zsh_sumZavailable_spaceZmin_bounded_sizeZsh_min_valsZsh_max_valsÚhintZstretch_ratior$   ÚshZsh_minZnot_mined_contribZnot_maxed_contribZsh_mins_availZsh_maxs_availZoversize_amtZundersize_amtZ	hint_origZsh_maxZdiffÚmarginZcontrib_amtZsh_availableZmultÚmnZmxr6   ÚjZsum_i_contributedZlast_heightZsh_available_iZcontrib_prop_sum_iÚnZcurr_heightÚdoneZmargin_heightÚkZavailable_shr   )r*   r'   r%   r!   r   Úlayout_hint_with_boundsk   s
   ,ÿ

ÿ







$
ÿÿ
þ
þ
ÿ
ÿÿÿ
ÿÿzLayout.layout_hint_with_bounds)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r	   r   r
   r   r   rB   Ú__classcell__r   r   r   r   r   ?   s   r   N)	rF   Ú__all__Z
kivy.clockr   Zkivy.uix.widgetr   Zkivy.compatr   r   r   r   r   r   Ú<module>   s
   7