U
    Pe~S                     @   s   d Z dZddlmZ ddlmZ ddlmZ ddlm	Z	 ddl
mZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ G dd deZG dd deZG dd deZG dd deZdS )a/  
Bubble
======

.. versionadded:: 1.1.0

.. image:: images/bubble.jpg
    :align: right

The :class:`Bubble` widget is a form of menu or a small popup with an arrow
arranged on one side of it's content.

The :class:`Bubble` contains an arrow attached to the content
(e.g., :class:`BubbleContent`) pointing in the direction you choose. It can
be placed either at a predefined location or flexibly by specifying a relative
position on the border of the widget.

The :class:`BubbleContent` is a styled BoxLayout and is thought to be added to
the :class:`Bubble` as a child widget. The :class:`Bubble` will then arrange
an arrow around the content as desired. Instead of the class:`BubbleContent`,
you can theoretically use any other :class:`Widget` as well as long as it
supports the 'bind' and 'unbind' function of the :class:`EventDispatcher` and
is compatible with Kivy to be placed inside a :class:`BoxLayout`.

The :class:`BubbleButton`is a styled Button. It suits to the style of
:class:`Bubble` and :class:`BubbleContent`. Feel free to place other Widgets
inside the 'content' of the :class:`Bubble`.


.. versionchanged:: 2.2.0
The properties :attr:`background_image`, :attr:`background_color`,
:attr:`border` and :attr:`border_auto_scale` were removed from :class:`Bubble`.
These properties had only been used by the content widget that now uses it's
own properties instead. The color of the arrow is now changed with
:attr:`arrow_color` instead of :attr:`background_color`.
These changes makes the :class:`Bubble` transparent to use with other layouts
as content without any side-effects due to property inheritance.

The property :attr:`flex_arrow_pos` has been added to allow further
customization of the arrow positioning.

The properties :attr:`arrow_margin`, :attr:`arrow_margin_x`,
:attr:`arrow_margin_y`, :attr:`content_size`, :attr:`content_width` and
:attr:`content_height` have been added to ease proper sizing of a
:class:`Bubble` e.g., based on it's content size.

BubbleContent
=============

The :class:`BubbleContent` is a styled BoxLayout that can be used to
add e.g., :class:`BubbleButtons` as menu items.

.. versionchanged:: 2.2.0
The properties :attr:`background_image`, :attr:`background_color`,
:attr:`border` and :attr:`border_auto_scale` were added to the
:class:`BubbleContent`. The :class:`BubbleContent` does no longer rely on these
properties being present in the parent class.

BubbleButton
============

The :class:`BubbleButton` is a styled :class:`Button` that can be used to be
added to the :class:`BubbleContent`.

Simple example
--------------

.. include:: ../../examples/widgets/bubble_test.py
    :literal:

Customize the Bubble
--------------------

You can choose the direction in which the arrow points::

    Bubble(arrow_pos='top_mid')
    or
    Bubble(size=(200, 40), flex_arrow_pos=(175, 40))

    Similarly, the corresponding properties in the '.kv' language can be used
    as well.

You can change the appearance of the bubble::

    Bubble(
        arrow_image='/path/to/arrow/image',
        arrow_color=(1, 0, 0, .5)),
    )
    BubbleContent(
        background_image='/path/to/background/image',
        background_color=(1, 0, 0, .5),  # 50% translucent red
        border=(0,0,0,0),
    )

    Similarly, the corresponding properties in the '.kv' language can be used
    as well.

-----------------------------
)BubbleBubbleButtonBubbleContent    )Image)Scatter)	BoxLayout)RelativeLayout)Button)ObjectProperty)StringProperty)OptionProperty)ListProperty)BooleanProperty)ColorProperty)NumericProperty)ReferenceListProperty)	EventLoop)dpc                   @   s   e Zd ZdS )BubbleExceptionN)__name__
__module____qualname__ r   r   3/tmp/pip-unpacked-wheel-xzebddm3/kivy/uix/bubble.pyr   x   s   r   c                   @   s   e Zd ZdZdS )r   a  A button intended for use in a BubbleContent widget.
    You can use a "normal" button class, but it will not look good unless the
    background is changed.

    Rather use this BubbleButton widget that is already defined and provides a
    suitable background for you.
    N)r   r   r   __doc__r   r   r   r   r   |   s   r   c                	   @   sR   e Zd ZdZeddddgZedZeddddgZ	e
ddddd	d
ddgdZdS )r   a  A styled BoxLayout that can be used as the content widget of a Bubble.

    .. versionchanged:: 2.2.0
    The graphical appearance of :class:`BubbleContent` is now based on it's
    own properties :attr:`background_image`, :attr:`background_color`,
    :attr:`border` and :attr:`border_auto_scale`. The parent widget properties
    are no longer considered. This makes the BubbleContent a standalone themed
    BoxLayout.
       z'atlas://data/images/defaulttheme/bubble   Z
both_loweroffZbothZx_onlyZy_onlyZy_full_x_lowerZx_full_y_loweroptionsN)r   r   r   r   r   Zbackground_colorr   Zbackground_imager   Zborderr   Zborder_auto_scaler   r   r   r   r      s    

	     r   c                       s  e Zd ZdZeddZedZeddddgZ	e
dZedddZed	Zed	ddZed
Zed
ZeeeZed
Zed
ZeeeZdddd
dddfdddd
dddfdddd
dddfdddddddfdddddddfdddddddfdddddddfdddddddfdddddddfdddd ddd!fdddd ddd"fdddd ddd#fd$Z fd%d&Zd'd( Z fd)d*Zd+d, Zd-d. Zd/d0 Zd1d2 Z d3d4 Z!d5d6 Z"d7d8 Z#d9d: Z$d;d< Z%d=d> Z&d?d@ Z' fdAdBZ(  Z)S )Cr   zABubble class. See module documentation for more information.
    T)Z	allownonez-atlas://data/images/defaulttheme/bubble_arrowr   
bottom_mid)left_topleft_midleft_bottomtop_lefttop_mid	top_right	right_top	right_midright_bottombottom_leftr    bottom_rightr   Nr   Zvertical)r   N      ?g?topxg      ?)r.   center_xgffffff?)r.   rightZ
horizontalNr   Z           lefty)r6   center_y)r6   r.      bottomr/   )r<   r0   )r<   r1   ir1   r7   )r1   r8   )r1   r.   )r*   r    r+   r)   r(   r'   r$   r%   r&   r#   r"   r!   c                    s   d | _ d | _d| _t| jd| jd| _| jjd | j_t	| jjd | j_
tddddd| _| j| j | jj| j_tdd| _| j| j t | _| j| j d | _t jf | |   d S )	NFz
scale-down)sourceZfit_modecolorr   r   )NN)	size_hintZdo_scaleZdo_rotationZdo_translation)r@   )content_flex_arrow_layout_params_temporarily_ignore_limitsr   arrow_imagearrow_color_arrow_imagetexture_sizewidthr   heightr   _arrow_image_scatter
add_widgetsizer   _arrow_image_scatter_wrapperr   _arrow_image_layoutZ_arrow_layoutsuper__init__reposition_inner_widgets)selfkwargs	__class__r   r   rP   x  s6    zBubble.__init__c                 O   s>   | j d kr2|| _ |j| _| j j| jd |   ntdd S )NrL   z1Bubble can only contain a single Widget or Layout)rA   rL   content_sizebindupdate_content_sizerQ   r   rR   widgetargsrS   r   r   r   rK     s    

zBubble.add_widgetc                    sN   || j kr6| j j| jd d | _ ddg| _|   d S t j|f|| d S )NrV   r   )rA   ZunbindrY   rW   rQ   rO   remove_widgetrZ   rT   r   r   r]     s    

zBubble.remove_widgetc                 C   s   |    d S Nadjust_positionrR   instancevaluer   r   r   on_content_size  s    zBubble.on_content_sizec                 C   s   |    d S r^   r_   ra   r   r   r   on_limit_to  s    zBubble.on_limit_toc                 C   s   |    d S r^   r_   ra   r   r   r   on_pos  s    zBubble.on_posc                 C   s   |    d S r^   rQ   ra   r   r   r   on_size  s    zBubble.on_sizec                 C   sF   | j | j_| jjd | j_t| jjd | j_| jj| j_| 	  d S )Nr   r   )
rD   rF   r>   rG   rH   r   rI   rJ   rL   rQ   ra   r   r   r   on_arrow_image  s
    
zBubble.on_arrow_imagec                 C   s   | j | j_d S r^   )rE   rF   r?   ra   r   r   r   on_arrow_color  s    zBubble.on_arrow_colorc                 C   s   |    d S r^   rg   ra   r   r   r   on_arrow_pos  s    zBubble.on_arrow_posc                 C   s   |   | _|   d S r^   )get_flex_arrow_layout_paramsrB   rQ   ra   r   r   r   on_flex_arrow_pos  s    
zBubble.on_flex_arrow_posc                    s4  | j }|d krd S |\}}d|  kr0| jkrLn nd|  krJ| jksPn d S d|fd| j| fd|fd| j| fg}t|dd dd }ttj| }| jj  fd	d
}|dkrd||| jd|d< nb|dkrd||| jd|d< nB|dkrd||| jd|d< n |dkr0d||| jd|d< |S )Nr   r    r%   r"   r(   c                 S   s   | d S r2   r   )valr   r   r   <lambda>      z5Bubble.get_flex_arrow_layout_params.<locals>.<lambda>)keyc                    s   | |   ||  S r^   r   )r/   lengthZarrow_widthr   r   calc_x0  s    z4Bubble.get_flex_arrow_layout_params.<locals>.calc_x0r,   r-   r9   r4   r;   r=   r5   )flex_arrow_posrH   rI   minlistr   ARROW_LAYOUTSrF   )rR   posr/   r7   Zbase_layouts_mapZbase_layout_keyZarrow_layoutrt   r   rs   r   rl     s0    2

z#Bubble.get_flex_arrow_layout_paramsc                 C   s   | j j| _d S r^   )rA   rL   rW   ra   r   r   r   rY     s    zBubble.update_content_sizec                 C   s   | j d k	r| js| j tjkr2d\}}| j j\}}n | j j}| j j}| j j}| j j}d| _|| jkrl|| jk st	|t
|| j | j| _|| jkr|| jk st
|| j t	|| j| _d| _d S )Nr   r   TF)limit_torC   r   ZwindowrL   r/   r7   r.   r1   maxrv   rH   rI   )rR   Zlim_xZlim_yZlim_topZ	lim_rightr   r   r   r`     s    zBubble.adjust_positionc                    s  | j }| j}| j}| j}t| jD ]}t | q"| jd ksF|d krJd S | j	d k	r\| j	}nt
j| j }|\}}}	}
}|
|_|jd |_||_|	|_|jd |_|| _||g}d\}}| jr|d dkr|j}q|d dkr|j}n
|d |d d | D ]}t | q||f| _d S )Nr   rz   r   hv)rN   rJ   rM   rA   rw   childrenrO   r]   ZcanvasrB   r   rx   	arrow_posZrotationZbboxrL   Zpos_hintr@   Zorientation
show_arrowrH   rI   poprK   arrow_margin)rR   Zarrow_image_layoutZarrow_image_scatterZarrow_image_scatter_wrapperrA   childZlayout_paramsZbubble_orientationZwidget_orderZarrow_size_hintZarrow_rotationZarrow_pos_hintZwidgets_to_addarrow_margin_xarrow_margin_yr[   rT   r   r   rQ   	  sD    

zBubble.reposition_inner_widgets)*r   r   r   r   r
   rA   r   rD   r   rE   r   r   r   r   r   ru   r{   r   r   r   r   r   Zcontent_widthZcontent_heightrW   rx   rP   rK   r]   rd   re   rf   rh   ri   rj   rk   rm   rl   rY   r`   rQ   __classcell__r   r   rT   r   r      s^   
	
		



!	'r   N)r   __all__Zkivy.uix.imager   Zkivy.uix.scatterr   Zkivy.uix.boxlayoutr   Zkivy.uix.relativelayoutr   Zkivy.uix.buttonr	   Zkivy.propertiesr
   r   r   r   r   r   r   r   Z	kivy.baser   Zkivy.metricsr   	Exceptionr   r   r   r   r   r   r   r   <module>   s(   d>