U
    PeP                    @   s  d Z ddlZddlZddlZddlmZ ddlmZ ddlm	Z	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mZ ddlmZ ddlmZm Z  ddl!m"Z"m#Z#m$Z$m%Z%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l0m1Z1 ddl2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z;m<Z< dZ=dekrpdd Z>nddlm>Z> ej?Z@ejAZBejCZDejEZFe@ddd e@d dd d!ZGd"ZHeGeHB ZIdaJdaKdZLeZMg ZNejd#kZOd$ZPd ZQZRereSd%d&ZPeTd'd(ZQd)UeTd'd*ZRdekrBd+d, ZVdd-lWmXZX eX YeVd. G d/d0 d0e/e1ZZG d1d2 d2e.Z[G d3d4 d4ee,Z\e]d5krdd6l^m_Z_ dd7l`maZa dd8lbmcZc dd9ldmeZe e_d:ZfG d;d< d<eaZgeg h  dS )=a  
Text Input
==========

.. versionadded:: 1.0.4

.. image:: images/textinput-mono.jpg
.. image:: images/textinput-multi.jpg

The :class:`TextInput` widget provides a box for editable plain text.

Unicode, multiline, cursor navigation, selection and clipboard features
are supported.

The :class:`TextInput` uses two different coordinate systems:

* (x, y) - coordinates in pixels, mostly used for rendering on screen.
* (col, row) - cursor index in characters / lines, used for selection
  and cursor movement.


Usage example
-------------

To create a multiline :class:`TextInput` (the 'enter' key adds a new line)::

    from kivy.uix.textinput import TextInput
    textinput = TextInput(text='Hello world')

To create a singleline :class:`TextInput`, set the :class:`TextInput.multiline`
property to False (the 'enter' key will defocus the TextInput and emit an
:meth:`TextInput.on_text_validate` event)::

    def on_enter(instance, value):
        print('User pressed enter in', instance)

    textinput = TextInput(text='Hello world', multiline=False)
    textinput.bind(on_text_validate=on_enter)

The textinput's text is stored in its :attr:`TextInput.text` property. To run a
callback when the text changes::

    def on_text(instance, value):
        print('The widget', instance, 'have:', value)

    textinput = TextInput()
    textinput.bind(text=on_text)

You can set the :class:`focus <kivy.uix.behaviors.FocusBehavior>` to a
Textinput, meaning that the input box will be highlighted and keyboard focus
will be requested::

    textinput = TextInput(focus=True)

The textinput is defocused if the 'escape' key is pressed, or if another
widget requests the keyboard. You can bind a callback to the focus property to
get notified of focus changes::

    def on_focus(instance, value):
        if value:
            print('User focused', instance)
        else:
            print('User defocused', instance)

    textinput = TextInput()
    textinput.bind(focus=on_focus)

See :class:`~kivy.uix.behaviors.FocusBehavior`, from which the
:class:`TextInput` inherits, for more details.


Selection
---------

The selection is automatically updated when the cursor position changes.
You can get the currently selected text from the
:attr:`TextInput.selection_text` property.

Filtering
---------

You can control which text can be added to the :class:`TextInput` by
overwriting :meth:`TextInput.insert_text`. Every string that is typed, pasted
or inserted by any other means into the :class:`TextInput` is passed through
this function. By overwriting it you can reject or change unwanted characters.

For example, to write only in capitalized characters::

    class CapitalInput(TextInput):

        def insert_text(self, substring, from_undo=False):
            s = substring.upper()
            return super().insert_text(s, from_undo=from_undo)

Or to only allow floats (0 - 9 and a single period)::

    class FloatInput(TextInput):

        pat = re.compile('[^0-9]')
        def insert_text(self, substring, from_undo=False):
            pat = self.pat
            if '.' in self.text:
                s = re.sub(pat, '', substring)
            else:
                s = '.'.join(
                    re.sub(pat, '', s)
                    for s in substring.split('.', 1)
                )
            return super().insert_text(s, from_undo=from_undo)

Default shortcuts
-----------------

=============== ========================================================
   Shortcuts    Description
--------------- --------------------------------------------------------
Left            Move cursor to left
Right           Move cursor to right
Up              Move cursor to up
Down            Move cursor to down
Home            Move cursor at the beginning of the line
End             Move cursor at the end of the line
PageUp          Move cursor to 3 lines before
PageDown        Move cursor to 3 lines after
Backspace       Delete the selection or character before the cursor
Del             Delete the selection of character after the cursor
Shift + <dir>   Start a text selection. Dir can be Up, Down, Left or
                Right
Control + c     Copy selection
Control + x     Cut selection
Control + v     Paste clipboard content
Control + a     Select all the content
Control + z     undo
Control + r     redo
=============== ========================================================

.. note::
    To enable Emacs-style keyboard shortcuts, you can use
    :class:`~kivy.uix.behaviors.emacs.EmacsBehavior`.

    N)environ)ref)chainislice)	Animation)	EventLoop)Cache)Clock)Config)Window)inch)boundaryplatform)FocusBehavior)LabelDEFAULT_FONT)Color	Rectangle
PushMatrix	PopMatrixCallback)	Transform)Texture)Widget)Bubble)ButtonBehavior)Image)
StringPropertyNumericPropertyBooleanPropertyAliasPropertyOptionPropertyListPropertyObjectPropertyVariableListPropertyColorPropertyBoundedNumericProperty)	TextInputZKIVY_DOCc                  O   s   dd }|S )Nc                    s    fdd}|S )Nc                     s
    | |S N )argskwargsfuncr)   6/tmp/pip-unpacked-wheel-xzebddm3/kivy/uix/textinput.pydecorated_func   s    z9triggered.<locals>.decorator_func.<locals>.decorated_funcr)   )r-   r/   r)   r,   r.   decorator_func   s    z!triggered.<locals>.decorator_funcr)   )___r0   r)   r)   r.   	triggered   s    r3   )r3   textinput.labelg      N@timeouttextinput.width      darwinFkivyZdesktopZwidgetsscroll_timeoutz{}spscroll_distancec                  G   sP   t d t d td d  D ].}| }|d kr:t| q|  |  qd S )Nr4   r7   )Cache_remove_textinput_listremove_trigger_refresh_text_refresh_hint_text)lwr	textinputr)   r)   r.   _textinput_clear_cache   s    rF   )get_contextTc                       sJ   e Zd Ze Ze Ze Z fddZdd Zdd Z	 fddZ
  ZS )	Selectorc              	      sj   t  jf | d| _| j | _| jj t| j	 t
  t | _W 5 Q R X | jj t  W 5 Q R X d S )NT)super__init__Zalways_releasetargetget_window_matrixmatrixcanvasbeforer   update_transformr   r   	transformafterr   selfr+   	__class__r)   r.   rJ      s    


zSelector.__init__c                 C   s6   | j  }| j|kr2|| _| j  | j| j d S r(   )rK   rL   rM   rQ   identity)rT   cbrM   r)   r)   r.   rP     s
    


zSelector.update_transformc                    s    | j   | fdd d S )Nc                    s     | |dd d S Nr   r9   Ztransform_pointxyrM   r)   r.   <lambda>      z*Selector.transform_touch.<locals>.<lambda>rM   Zinverseapply_transform_2drT   touchr)   r^   r.   transform_touch  s    

zSelector.transform_touchc                    sh   | j tjk	rd S zH|  | | | j|j | _| j	|j
 rJtj| t |W S |  X d S r(   )parentr   windowpoppushre   topr]   _touch_diffcollide_pointposr   ignored_touchappendrI   on_touch_downrc   rU   r)   r.   rp     s    
zSelector.on_touch_down)__name__
__module____qualname__r#   rg   rK   rM   rJ   rP   re   rp   __classcell__r)   r)   rU   r.   rH      s   rH   c                       s   e Zd ZedZedZedZedZedZedZ	dZ
 fddZdd Zdd Z fdd	Z fd
dZdd Zdd Zdd Zdd Zdd Z  ZS )TextInputCutCopyPasteNc              	      sz   d| _ t jf | t| jd| _| j | _	| j
j t| j t  t | _W 5 Q R X | j
j t  W 5 Q R X d S )Nnormal      ?)moderI   rJ   r	   schedule_interval_check_parent_check_parent_evrE   rL   rM   rN   rO   r   rP   r   r   rQ   rR   r   rS   rU   r)   r.   rJ   1  s    


zTextInputCutCopyPaste.__init__c                 C   s6   | j  }| j|kr2|| _| j  | j| j d S r(   )rE   rL   rM   rQ   rW   )rT   rX   mr)   r)   r.   rP   ?  s
    


z&TextInputCutCopyPaste.update_transformc                    s    | j   | fdd d S )Nc                    s     | |dd d S rY   rZ   r[   r^   r)   r.   r_   I  r`   z7TextInputCutCopyPaste.transform_touch.<locals>.<lambda>ra   rc   r)   r^   r.   re   F  s    

z%TextInputCutCopyPaste.transform_touchc                    sJ   z:|  | | | j|j r,tj| t 	|W S |   X d S r(   )
rh   ri   re   rl   rm   r   rn   ro   rI   rp   rc   rU   r)   r.   rp   K  s    
z#TextInputCutCopyPaste.on_touch_downc                    sX   zH|  | | | jjD ]}t||jkr||_ q:qt 	|W S |   X d S r(   )
rh   ri   re   contentchildrenr   Z	grab_listgrab_currentrI   on_touch_up)rT   rd   childrU   r)   r.   r   U  s    
z!TextInputCutCopyPaste.on_touch_upc                 C   s   |rt sts|  d S r(   )	Clipboard_is_desktop_ensure_clipboardrT   instancevaluer)   r)   r.   on_textinputa  s    z"TextInputCutCopyPaste.on_textinputc                 C   sH   | j }|d k	r"||jkrq"|j}q|d krD| j  | j rD| j   d S r(   )rE   rf   r{   cancel_hide_cut_copy_paste)rT   dtrf   r)   r)   r.   rz   f  s    

z#TextInputCutCopyPaste._check_parentc                 C   s   | j }| j}|r|| j  |dkrFd| j_| jg}|jsf|| j n |jrV| j	f}n| j
| j	| jf}|D ]}| j| qjd S )Npaster8   )rE   rx   r}   Zclear_widgetsbut_selectallopacityreadonlyro   	but_pastebut_copybut_cut
add_widget)rT   r   r   rf   rx   Zwidget_listZwidgetr)   r)   r.   	on_parents  s    

zTextInputCutCopyPaste.on_parentc                    s    j }|dkr||j nj|dkr.|  nX|dkr@|  nF|dkr|  d _tddd}|j fd	d
d |	 j
 d S    d S )Ncutcopyr   Z	selectall r   gZd;O?r   dc                     s       jS r(   )r   rf   r*   rT   r)   r.   r_     s    z*TextInputCutCopyPaste.do.<locals>.<lambda>Zon_complete)rE   _cutselection_textr   r   
select_allrx   r   bindstartr   hide)rT   actionrE   animr)   r   r.   do  s    

zTextInputCutCopyPaste.doc                    s>   j   sd S tddd}|j fddd | d S )Nr   ?r   c                     s
     S r(   )remove_widgetr   rf   rT   r)   r.   r_     r`   z,TextInputCutCopyPaste.hide.<locals>.<lambda>r   )rf   r   r   r   )rT   r   r)   r   r.   r     s    zTextInputCutCopyPaste.hide)rq   rr   rs   r#   rE   r   r   r   r   rM   r{   rJ   rP   re   rp   r   r   rz   r   r   r   rt   r)   r)   rU   r.   ru      s"   
ru   c                       s  e Zd ZdZdZdZ fddZdd Zd!dd	Zd
d Z	dd Z
dd Zdd ZedZdd Zd"ddZd#ddZdd Zdd Zdd Zd d! Zd$d#d$Zd%d& Zed'Zd%d(d)Zd&d*d+Zd'd,d-Zd(d.d/Zd)d0d1Zed2d3 Z d*d4d5Z!d6d7 Z"d+d8d9Z#d:d; Z$d<d= Z%d,d>d?Z&d@dA Z'd-dBdCZ(dDdE Z)dFdG Z*d.dIdJZ+dKdL Z,dMdN Z-dOdP Z. fdQdRZ/dSdT Z0dUdV Z1dWdX Z2dYdZ Z3d[d\ Z4d]d^ Z5d_d` Z6dadb Z7d/dcddZ8dedf Z9d0dhdiZ:d1djdkZ;e<dldm Z=dndo Z>dpdq Z?drds Z@dtdu ZAd2dvdwZBdxdy ZCdzd{ ZDd|d} ZEd~d ZFdd ZGdd ZHdd ZIdd ZJdd ZKdd ZLdd ZMdd ZNdd ZOdd ZPdd ZQdd ZRdd ZSdd ZTdd ZUdd ZVdd ZWdd ZXdd ZYdd ZZdd Z[dd Z\dd Z]dd Z^d3ddZ_dZ`dd Zadd Zbd4ddZcd5ddZd fddZedd Zfdd Zgdd ZhddĄ ZiejdgZkeldddƍZm fddȄZn fddʄZodd̄ Zpdd΄ ZqddЄ Zrelg Zselg ZteudŃZvedѡZwedҡZxeudZyeze]ddgdԍZ{eze\ddgdԍZ|eudZ}eudŃZ~eudŃZeudŃZeudZejdՃZeudŃZddׄ Zddل Zeddۍdd݄ ZezeeZdd߄ ZezedddԍZdd ZezedddԍZeze[ddddZeddddgZedZedZedZeddgdddZdd ZeddgdddZdd ZeddddgZedddddgdZedZedZeddddgZelddddgZejdZejdZejdZeddddgZeddddgZeddddgZeue Zeue Zeue ZeeZeeZdd ZezedZdd ZezedZejdgZd d Zdd Zdd ZezeedddZejeZedZejdddƍZejdddƍZeddd	d
ddgdŐdZejdddƍZejdgZdd Zdd ZezeeddԍZeddddgZeudZeudŃZeudŃZŐdd ZezeƐdddZedZeɐdddZedddƍZejdZ͐dd ZejdZϐdd ZejdZѐdd  ZeudŃZӇ  ZS (6  r'   a
  TextInput class. See module documentation for more information.

    :Events:
        `on_text_validate`
            Fired only in multiline=False mode when the user hits 'enter'.
            This will also unfocus the textinput.
        `on_double_tap`
            Fired when a double tap happens in the text input. The default
            behavior selects the text around the cursor position. More info at
            :meth:`on_double_tap`.
        `on_triple_tap`
            Fired when a triple tap happens in the text input. The default
            behavior selects the line around the cursor position. More info at
            :meth:`on_triple_tap`.
        `on_quad_touch`
            Fired when four fingers are touching the text input. The default
            behavior selects the whole text. More info at
            :meth:`on_quad_touch`.

    .. warning::
        When changing a :class:`TextInput` property that requires re-drawing,
        e.g. modifying the :attr:`text`, the updates occur on the next
        clock cycle and not instantly. This might cause any changes to the
        :class:`TextInput` that occur between the modification and the next
        cycle to be ignored, or to use previous values. For example, after
        a update to the :attr:`text`, changing the cursor in the same clock
        frame will move it using the previous text and will likely end up in an
        incorrect position. The solution is to schedule any updates to occur
        on the next clock cycle using
        :meth:`~kivy.clock.ClockBase.schedule_once`.

    .. Note::
        Selection is cancelled when TextInput is focused. If you need to
        show selection when TextInput is focused, you should delay
        (use Clock.schedule) the call to the functions for selecting
        text (select_all, select_text).

    .. versionchanged:: 1.10.0
        `background_disabled_active` has been removed.

    .. versionchanged:: 1.9.0

        :class:`TextInput` now inherits from
        :class:`~kivy.uix.behaviors.FocusBehavior`.
        :attr:`~kivy.uix.behaviors.FocusBehavior.keyboard_mode`,
        :meth:`~kivy.uix.behaviors.FocusBehavior.show_keyboard`,
        :meth:`~kivy.uix.behaviors.FocusBehavior.hide_keyboard`,
        :meth:`~kivy.uix.behaviors.FocusBehavior.focus`,
        and :attr:`~kivy.uix.behaviors.FocusBehavior.input_type`
        have been removed since they are now inherited
        from :class:`~kivy.uix.behaviors.FocusBehavior`.

    .. versionchanged:: 1.7.0
        `on_double_tap`, `on_triple_tap` and `on_quad_touch` events added.

    .. versionchanged:: 2.1.0
        :attr:`~kivy.uix.behaviors.FocusBehavior.keyboard_suggestions`
        is now inherited from :class:`~kivy.uix.behaviors.FocusBehavior`.
    )on_text_validateon_double_tapon_triple_tapon_quad_touchNc                    s  t  jd _|dd _ddg _d _d _d  _	d _
d  _d  _d  _d  _d  _d  _d  _g  _g  _g  _g  _g  _g  _d  _d  _tdd _d _d _   d _d _ d _!d _"d _#d  _$d  _%t j j&d	dd
 _'d  _(d _)d _*d _+d _,d _-ddddddddddddddddddd _.t/ j0f |  j1} j2} j3} j4}|d| |d| |d | |d!| |d"| |d#|  fd$d%}|d&| |d'| |d| |d| |d(| |d)| |d*| |d+| |d,| |d-| |d. j5 |  j6 t  j7 } _8t  j9d/ _:t  j; _<t  j= _>|   ?  |d+| |d(| t@AtB tCjD tEd0kr F  d S )1Nis_focusableTr   Fr   r;   Zkeyboard_moderw   )intervalr   r   	backspaceenterdel	cursor_upcursor_downcursor_rightcursor_leftcursor_home
cursor_endcursor_pgupcursor_pgdownshift_Lshift_Rctrl_Lctrl_Ralt_Lalt_R)         i  i  i  i  i  i  i  i  i  i/  i0  i1  i2  i4  i3  	font_size	font_namefont_contextfont_familybase_directiontext_languagec                    s>   |rt r jsd _|s jr,t r4 jdkr4d _nd _d S )NFsystemT)r   
allow_copyr   disabled_keyboard_mode	_editable)r   r   r   r)   r.   handle_readonly;  s    z+TextInput.__init__.<locals>.handle_readonlypadding	tab_widthsizepasswordpassword_maskrm   halignr   focusg?linux)Gr	   create_trigger_update_graphics_update_graphics_evgetr   _cursor
_selection_selection_finished_selection_touchr   _selection_from_selection_to_selection_callback_handle_left_handle_right_handle_middle_bubble_lines_flags_lines_labels_lines_rects_hint_text_flags_hint_text_labels_hint_text_rects_label_cached_line_optionsr
   r   _command_mode_command
reset_undo_touch_count_ctrl_l_ctrl_r_alt_l_alt_r_refresh_text_from_property_ev_long_touch_ev_do_blink_cursor_do_blink_cursor_ev_refresh_line_options_ev_scroll_distance_x_scroll_distance_y_enable_scroll_have_scrolled_visible_lines_rangeinteresting_keysrI   rJ   fbind_trigger_refresh_line_options_update_text_options_trigger_update_graphics_on_textinput_focusedr   _position_handles_trigger_position_handles_show_handles_trigger_show_handles_reset_cursor_blink_trigger_cursor_reset_update_cutbuffer_trigger_update_cutbufferrA   r?   ro   r   r'   _reload_remove_observerr   r   )rT   r+   r  Zrefresh_line_optionsZupdate_text_optionsZtrigger_update_graphicsr   ZhandlesrU   r   r.   rJ     s     
  





	










 


zTextInput.__init__c                 C   s   d S r(   r)   r   r)   r)   r.   r   f  s    zTextInput.on_text_validatec           	      C   s   |s
| j }zz| j}|sW dS | j}|\}}ttt|t|||D ]&\}}}|t|7 }|t@ rD|d7 }qD|| t@ r|d7 }|W S  tk
r   Y dS X dS )z3Return the cursor index in the text/value.
        r   r8   N)	cursor_linesr   ziprangeminlenFL_IS_LINEBREAK
IndexError)	rT   r  linesflagsindex
cursor_rowr1   lineflagr)   r)   r.   cursor_indexi  s*    
zTextInput.cursor_indexc                 C   sP   d}t | j}t | j}| j}|rL|t|k rL| || d| | j| j}|S )z5Get the cursor x offset on the current line.
        r   N)intr  
cursor_colr  r  _get_text_widthr   r   )rT   offsetrowcolr  r)   r)   r.   cursor_offset  s    

zTextInput.cursor_offsetc                 C   s   t |dt| j}|dkrdS | j}| j}|s2dS d}t|D ]L\}}|t| }|| t@ rn|d7 }|d7 }||kr|| |f  S |}q>t|t|fS )z=Return the (col, row) of the cursor from text index.
        r   r   r8   )r   r  textr   r  	enumerater  r   )rT   r  r  r  ir$  r  countr)   r)   r.   get_cursor_from_index  s"    zTextInput.get_cursor_from_indexc                 C   sR   ||k rt dt| j}t|d|| _t|d|| _d| _| d |   dS )aG   Select a portion of text displayed in this TextInput.

        .. versionadded:: 1.4.0

        :Parameters:
            `start`
                Index of textinput.text from where to start selection
            `end`
                Index of textinput.text till which the selection should be
                displayed
        zend must be superior to startr   TN)		Exceptionr  r'  r   r   r   r   _update_selection_update_graphics_selection)rT   r   endZtext_lengthr)   r)   r.   select_text  s    

zTextInput.select_textc                 C   s   |  dt| j dS )z^ Select all of the text displayed in this TextInput.

        .. versionadded:: 1.4.0
        r   N)r0  r  r'  r   r)   r)   r.   r     s    zTextInput.select_allz^(\s*|)c                 C   sX   |   }|dkrT| j}|dd|}|dkrT||d | }| j| }||7 }|S )Nr   
r   r8   )r  r'  rfind	re_indentmatchgroup)rT   	substringr  Z_textZ
line_startr  indentr)   r)   r.   _auto_indent  s    zTextInput._auto_indentFc                 C   s  | j }| j}| js|r| j s dS t|tr4|d}| jrF|dd}| t	j
 |st| jrt| jrt|dkrt| |}| j}|dkr|||}|sdS | j\}}|  }|| }	t|}
|	d| | |	|d  }|dk	r|dkrt| j|sdS n|dkrt| j|sdS | || |
dks|dks|d	krN|| tks|d t|k rr||d  tks| || j| j| j| jd
  | jd  kr| ||\}}}}}| d||||| | ||
 | _|  |||
 || dS )zInsert new text at the current cursor position. Override this
        function in order to pre-process text for input validation.
        Nutf8
r1  )Nr   floatr   r;  r8    r   r9   insert)!r  r   r   
isinstancebytesdecodereplace_crlfreplace_hide_handlesr   rg   	multilineauto_indentr8  input_filterr  r  r  rer4  _insert_int_pat_insert_float_pat_set_line_textr  r"  r   r   widthr   _get_line_from_cursor_refresh_text_from_propertyr+  _set_unredo_insert)rT   r6  	from_undor  r   rx   r%  r$  cindexr'  len_strnew_textr   finishr  lines_flags	len_linesr)   r)   r.   insert_text  s    








         zTextInput.insert_textc           	      C   s   |d kr| j }|d kr| j}|}|d }|dkrP|| tkrP|d8 }|| | }|}t|t|D ]}|| tkrb|d } qqb|}|d|||d   }| |\}}tdt|}|||||fS )Nr8   r   r   )r  r   r  r  r  join_split_smartmax)	rT   r   rR  r  rT  rS  _nextr)  rU  r)   r)   r.   rL    s&    zTextInput._get_line_from_cursorc                 C   s.   |rd S | j d||f||fd g | _d S )Nr=  undo_commandredo_command_undoro   _redo)rT   ciZscir6  rO  r)   r)   r.   rN  4  s    zTextInput._set_unredo_insertc                 C   s   g  | _ | _dS )zQReset undo and redo lists from memory.

        .. versionadded:: 1.3.0

        N)r`  r_  r   r)   r)   r.   r   ?  s    zTextInput.reset_undoc           
      C   s   z| j  }|d d }| j}|dkrJ|d \}}||| _| |d n|dkrn||d | _| jdd nb|dkr|d d	d
 \}}}| |||d n2|d \}}	|| _|	| _d| _	| 
d ||| _| j| W n tk
r   Y nX d
S )zDo redo operation.

        .. versionadded:: 1.3.0

        This action re-does any command that has been un-done by
        do_undo/ctrl+z. This function is automatically called when
        `ctrl+r` keys are pressed.
        r\  r   r=  r]  TbkspcrO  shiftlnr8   N)r`  rh   r+  r  rV  do_backspace_shift_linesr   r   r   delete_selectionr_  ro   r  )
rT   x_item	undo_typeZ_get_cusror_from_indexrP  r6  	directionrowsr  scindexr)   r)   r.   do_redoG  s.    	



zTextInput.do_redoc           
      C   s0  z| j  }|d d }| |d d | _|dkrh|d dd \}}|| _|| _d| _| d n|dkr|d d d }|d d	 }| |d |d
kr| | 	 d | _nP|dkr|d dd \}}}	| 
|||	d n |d dd d }| |d | j| W n tk
r*   Y nX dS )zDo undo operation.

        .. versionadded:: 1.3.0

        This action un-does any edits that have been made since the last
        call to reset_undo().
        This function is automatically called when `ctrl+z` keys are pressed.
        r\  r   r8   r=  NTrb  r9      r   rd  )r_  rh   r+  r  r   r   r   rg  rV  r  rf  r`  ro   r  )
rT   rh  ri  rP  rl  r6  rx   rj  rk  r  r)   r)   r.   do_undol  s4    	

zTextInput.do_undorb  c                 C   sr  | j s| jrdS | j\}}| j}| j}|| }|  }|dkrJ|dkrJdS |}	|dkr|| tkrxd}
||d  | }n@t||d  dkr||d  d nd}
||d  dd | }| |d | | 	| |d }	n4||d  }
|d|d  ||d  }| || | 
|	|\}	}}}}| |dkr8dnd|	|||| | |d | _| ||d |
|| dS )	a   Do backspace operation from the current cursor position.
        This action might do several things:

            - removing the current selection if available.
            - removing the previous char and move the cursor back.
            - do nothing, if we are at the start.

        Nr   r1  r8   r   r   r=  r   )r   _ime_compositionr  r  r   r  r  r  rJ  _delete_linerL  rM  r+  _set_unredo_bkspc)rT   rO  rx   r%  r$  r  r   r'  r  r   r6  rR  rS  r  Z	lineflagsrU  r)   r)   r.   re    sT    

$


      zTextInput.do_backspacec                 C   s,   |rd S | j d|||f|d g | _d S )Nrb  r[  r^  )rT   Zol_indexZ	new_indexr6  rO  rx   r)   r)   r.   rr    s    
zTextInput._set_unredo_bkspcz\s+c           	      C   s  |p
|   }|dkr| jS | j}| |\}}|dkrJ|d8 }t|| }t| j|| d|}|s|dkr|dkrzdS |d8 }t|| }qJd|fS |d }| }||krt|dkr|d }| }n6|	 dkr|dkrdS |d8 }t|| }qJd|fS |}||fS )Nr   r8   r   r   )
r  r  r  r+  r  list_re_whitespacefinditerr/  r   )	rT   r  rm   r  r%  r$  matchesr4  mposr)   r)   r.   _move_cursor_word_left  s@    

z TextInput._move_cursor_word_leftc           
      C   sJ  |p
|   }| |\}}| j}t|d }||krL|t|| krL||fS |t|| krh|d7 }d}t| j|| |}|s|t|| kr||kr||fS |d7 }d}qht|| |fS |d }| }	|	|kr>t|dkr|d }| }	nF| t|| kr.||kr ||fS |d7 }d}qht|| |fS |	}||fS Nr8   r   )	r  r+  r  r  rt  ru  rv  r   r/  )
rT   r  rm   r%  r$  r  Zmrowrw  r4  rx  r)   r)   r.   _move_cursor_word_right  sB    


z!TextInput._move_cursor_word_rightc                 C   s`   |d kr|}|  |d }|  |\}}| ||r:|d n|\}}| d|f| d|ffS rz  )r+  _expand_rowsr  )rT   ZifromZitorfromZrtcolrtor)   r)   r.   _expand_range%  s    zTextInput._expand_rangec                 C   s   |d ks||kr|d }| j }tt| j}|dkrN||d  t@ sN|d8 }q,t|d }d|  k rn|k rn n||d  t@ s|d7 }qZtd|t||fS rz  )r  rt  reversedr   FL_IS_NEWLINEr  rY  r  )rT   r}  r~  r  r  Zrmaxr)   r)   r.   r|  /  s    
(
zTextInput._expand_rowsc              	      s>  j r|rj   nd S j}ttj}j}j}j}	d  |d k	rR|_|sFj	}
j
}|
sl|r|
|krtt|
|f\}
}|
|\}
}n \}
}|
d }|d }|
|f |dk r|dkr|d \}}||f||ff}n:|dkr|t|d k r|\}}||f||ff}n|\\}}\}}|dk r|| }}|| }}|| }|| }n$|| }}|| }}|| }|| }ttt|d | ||| ||| ||d  _|d | |||  |||  ||d   jd d < |d | |||  |||  ||d   _|d | |||  |||  ||d   _  || }|| }d|fd|ff jj| f_|s|| || f|| || ff}jd|d |jfd|||	fd g _ r: fdd}t|_ d S )Nr8   r   rd  r   r[  c                    s   j    d _d S r(   )r0  r   r   selrT   r)   r.   rX     s    
z"TextInput._shift_lines.<locals>.cb)r   r   r  rt  r  r   r   r   r  selection_fromselection_totuplesortedr  r  r+  r|  r  r   r  r!  r  r_  ro   r`  r	   schedule_once)rT   rj  rk  Z
old_cursorrO  r  r  labelsrectsZorig_cursorsindexeindexZsrowZerowZpsrowZperowZm1srowZm1erowZm2srowZm2erowZcdiffZxdiffZcsrowZcerowZ	undo_rowsrX   r)   r  r.   rf  ;  s    
























zTextInput._shift_linesc                 C   s   t | j| j| j  d S )zFhow much vertical distance hitting pg_up or pg_down will move
        r8   )r   heightline_heightline_spacingr   r)   r)   r.   pgmove_speed  s    
zTextInput.pgmove_speedc                 C   sh   | j r |r td| j| j | _n@| js>| j r>|r>| d d S t|d d}tt| j| |}||fS )Nr   r   r8   )	rD  rY  scroll_yr  r   rf  r  r  r  )rT   r%  r$  controlaltr)   r)   r.   _move_cursor_up  s    

zTextInput._move_cursor_upc                 C   s   | j r2|r2| j| j }tdt|| j| j | _nJ| jsP| j rP|rP| d d S t|d t	| j
d }tt	| j
| |}||fS Nr   r8   )rD  minimum_heightr  rY  r  r  r  r   rf  r  r  )rT   r%  r$  r  r  maxyr)   r)   r.   _move_cursor_down  s    

zTextInput._move_cursor_downc           	      C   s  | j s
dS | j\}}|dkrB| ||||}|r:|\}}ndS n|dkrp| ||||}|rh|\}}ndS nZ|dkrd}|rd}nB|dkr|rt| j d }t| j | }n|dkrtd|| j }tt| j | |}n|d	kr t|| j t| j d }tt| j | |}n| jr| j	r| j
| jk r|d
kr| j}| j
|kr|d8 }|rr|d8 }n|d8 }t| j | }qNn:| jr| j	r| j
| jkr|dkr| j}| j
|kr|d7 }t| j | |kr|d7 }n|d7 }d}qn|d
kr`| js(|r(|  \}}n6|dkrP|r^|d8 }t| j | }n|d | }}nj|dkr| js|r|  \}}nD|t| j | kr|t| j d k rd}|d7 }n|d | }}|o|dk}|r|   n
||f| _dS )a  Move the cursor relative to its current position.
        Action can be one of :

            - cursor_left: move the cursor to the left
            - cursor_right: move the cursor to the right
            - cursor_up: move the cursor on the previous line
            - cursor_down: move the cursor on the next line
            - cursor_home: move the cursor at the start of the current line
            - cursor_end: move the cursor at the end of current line
            - cursor_pgup: move one "page" before
            - cursor_pgdown: move one "page" after

        In addition, the behavior of certain actions can be modified:

            - control + cursor_left: move the cursor one word to the left
            - control + cursor_right: move the cursor one word to the right
            - control + cursor_up: scroll up one line
            - control + cursor_down: scroll down one line
            - control + cursor_home: go to beginning of text
            - control + cursor_end: go to end of text
            - alt + cursor_up: shift line(s) up
            - alt + cursor_down: shift line(s) down

        .. versionchanged:: 1.9.1

        Nr   r   r   r   r   r8   r   r   r   r   )r   r   )r  r  r  r  r  rY  r  r  r   r   r   r   r   ry  r{  r  )	rT   r   r  r  r%  r$  resultZcurrent_selection_toZdont_move_cursorr)   r)   r.   do_cursor_movement  s    













zTextInput.do_cursor_movementc                 C   s  | j \}}}}| j}| j| j }|| j }	| j}
| j}|
dkrF|
| nd}
| j| |
|  | }tt	t
|| d dt|d }| j}| j}| j}d}| j}| jp| j}|dko|od|k}|dkr| j| | }tdt|| | d }n6|dks|r*| j| | }tdt|| | }tdt|| D ]R}|| }|	| |||d	| || ||| ||d
  | k r<|}	 qq<t|| }	|	|fS )zEReturn the (col, row) of the cursor from an (x, y) position.
        r   rw   r8   autortlcenterr9   rightNg333333?)r   r  r  r  r\   r  scroll_xrj   r   r   roundr  r"  r   r   r   r   _resolved_base_dirrK  rY  _get_row_widthr  )rT   r\   r]   padding_leftpadding_toppadding_rightpadding_bottomr  dyZcursor_xr  r  Zcursor_yget_text_widthr   label_cachedZxoffr   base_dirauto_halign_rviewport_widthr)  Zline_yr)   r)   r.   get_cursor_from_xy:  s^    

  
zTextInput.get_cursor_from_xyc                 C   s4   |    | _| _d| _d| _d| _d| _|   dS )z+Cancel current selection (if any).
        FTNr   )r  r   r   r   r   r   r   r  r   r)   r)   r.   cancel_selectionv  s    zTextInput.cancel_selectionc                 C   sx  | j r
dS | tj | j}| j}| j\}}| js6dS | j}t	| j
| jf\}}| |}	| |}
| j|	d  d|	d  | j|
d  |
d d  }| |	d | | j|	d || jd|	d d  | j|
d d d  | jd|	d d  | j|
d d d  d\}}}}}| d|||
d |	d   ||| || _|| _| ||||| | |   | || _dS )z4Delete the current text selection (if any).
        Nr8   r   )r  rT  r   )r   rC  r   rg   r  r  r  r   r'  r  r   r   r+  r  rJ  rL  r   rM  _set_unredo_delselr  )rT   rO  r  r  cccrr'  abr   rS  cur_lineZ	start_delZ
finish_delr  rT  rU  r)   r)   r.   rg    sH    


  zTextInput.delete_selectionc                 C   s.   |rd S | j d||f||fd g | _d S )NZdelselr[  r^  )rT   r  r  r6  rO  r)   r)   r.   r    s    zTextInput._set_unredo_delselc                 C   s   t | jt | j }}||kr(|| }}|| _| j|| }| jsFdn| jrZ| j||  n|| _|sld| _	nt
t|| _	d| _|dkr|   dS )zUpdate selection text and order of from/to if finished is True.
        Can be called multiple times until finished is True.
        r   TNr   )r   r   r   r   r'  r   r   r   r   r   boolr  r   r.  )rT   finishedr  r  Z_selection_textr)   r)   r.   r-    s     

zTextInput._update_selectionc                 C   s<   d | _ | j| jkr8| j| jjddi}| j|tjdd d S )NrelativeFr   rx   )	r   r   r   to_local_touch_downrm   _show_cut_copy_paster   rg   )rT   r   rm   r)   r)   r.   
long_touch  s      zTextInput.long_touchc                 C   s   | j d k	r| j   d | _ d S r(   )r   r   r   r)   r)   r.   cancel_long_touch_event  s    

z!TextInput.cancel_long_touch_event .,:;!?'"<>()[]{}c                    s      jjj tdtd  tfdd|D  d tfdd|D t fdd d S )Nr   c                 3   s    | ]}d    |V  qd S r(   )r2  .0sr%  r  r)   r.   	<genexpr>  s     z)TextInput._select_word.<locals>.<genexpr>r8   c                 3   sB   | ]:} d   |dkr. d   |n
t  V  qd S )Nr   )findr  r  r  r)   r.   r    s   (c                    s        S r(   r0  r  )rP  r/  rT   r   r)   r.   r_     s   
z(TextInput._select_word.<locals>.<lambda>)	r  r!  r  r  rY  r  r  r	   r  )rT   
delimitersr)   )rP  r%  r/  r  rT   r   r.   _select_word  s    zTextInput._select_wordc                 C   s   |    dS )a8  This event is dispatched when a double tap happens
        inside TextInput. The default behavior is to select the
        word around the current cursor position. Override this to provide
        different behavior. Alternatively, you can bind to this
        event to provide additional functionality.
        N)r  r   r)   r)   r.   r     s    zTextInput.on_double_tapc                    s0     }|\ t fdd dS )a4  This event is dispatched when a triple tap happens
        inside TextInput. The default behavior is to select the
        line around current cursor position. Override this to provide
        different behavior. Alternatively, you can bind to this
        event to provide additional functionality.
        c                    s     S r(   r  r  r  rT   r  r)   r.   r_     r`   z)TextInput.on_triple_tap.<locals>.<lambda>N)r  r  r	   r  )rT   ra  r)   r  r.   r     s    zTextInput.on_triple_tapc                    s   t  fdd dS )a  This event is dispatched when four fingers are touching
        inside TextInput. The default behavior is to select all text.
        Override this to provide different behavior. Alternatively,
        you can bind to this event to provide additional functionality.
        c                    s      S r(   )r   r  r   r)   r.   r_     r`   z)TextInput.on_quad_touch.<locals>.<lambda>N)r	   r  r   r)   r   r.   r     s    zTextInput.on_quad_touchc                    sT  | j r
d S |j}| j| sdS t |r.dS | jr<|   d|jkrt|j	drt|jdd  }|dkr| j
r| jdkrtd| j| j| j  | _|   n&| jdkrtd| j| j | _|   |dkrp| j
rtd| j| j }| j|k rpt|| j| j| j  | _|   nV| d| jd  | jd	  }td|| j }| j|k rpt|| j| j | _|   dS ||  |  jd
7  _|jr| d |jr| d | jdkr| d || _d| _d| _d| _d| _ | !t"j# t$%| j&d| _'| j(| | _)| j*s | +| j t,rPd|jkrP|jdkrP| -t,.  dS dS )NFTbuttonZscroll   Zdownr   Zupr9   r8   r   r      r   rw   middle)/r   rm   rl   rI   rp   r   r  Zprofiler  
startswithrD  r  rY  r  lines_to_scrollr  r  r  r  r  r  r   rK  Zgrabr   is_double_tapdispatchis_triple_tapr  r   r   r   r   r   r   rg   r	   r  r  r   r  r  scroll_from_swipe_cancel_update_selection	CutBufferrV  Zget_cutbuffer)rT   rd   Z	touch_posZscroll_typemax_scroll_yminimum_widthmax_scroll_xrU   r)   r.   rp     s    









zTextInput.on_touch_downc                 C   s0   | j s,|   || _ |   | _| _|   d S r(   )r   r  r  r   r   r-  rc   r)   r)   r.   r  R  s
    z"TextInput._cancel_update_selectionc                 C   s~   |j | k	rd S | js2||  | j|kr.d | _dS | jrB| | | jsz| j|krz| |j|j	| _
|  | _|   dS d S )NFT)r   r   ungrabr   r  scroll_text_from_swiper   r  r\   r]   r  r  r   r-  rc   r)   r)   r.   on_touch_moveY  s    




zTextInput.on_touch_movec                 C   s8  |j | k	rd S ||  |  jd8  _|   | js8dS |jpL|jpL| jdk}| jsd|sd| | j	 t
j}| j| jkr| |j| | j|kr4|  | _| d | jr0| j| jkr0|   | j}|d krt| j|| ddd | _}|j| j| j| jd | jjs$| jr$t
jj|d	d
 | jdd dS d S )Nr8   Fr  TNN45dpr  )sourcerg   rK   	size_hintr   Zon_pressr  Z
on_releaserR   rN   r  r  ) r   r  r   r  r   r  r  r   r  r  r   rg   r   r   r  rm   r   r  r-  use_handlesrC  r   rH   handle_image_middler   _handle_pressed_handle_move_handle_releasedrf   r'  r   r  )rT   rd   Zprioritized_touch_typeswinhandle_middler)   r)   r.   r   k  sN    





zTextInput.on_touch_upc                 C   s"  |j |j d }|  jt|j7  _|  jt|j7  _| js|| jkr`| j| j	ks| j| j	ks|| jkrndS d| _
| | j dS d| _|   | jrtd| j| j }ttd| j|j || _nH| d| jd  | jd  }td|| j }ttd| j|j || _|   |   dS )Ni  FTr   r9   )Ztime_updateZ
time_startr   absZdxr   r  r   r<   r=   r   r  r  r  rD  rY  r  r  r  r  r  r   rK  r  r  r  )rT   rd   _scroll_timeoutr  r  r  r)   r)   r.   r    sJ    


z TextInput.scroll_text_from_swipec                 C   s0   |    | j| j }}||kr,|| | _| _d S r(   )r   r   r  r   )rT   r   from_to_r)   r)   r.   r    s    zTextInput._handle_pressedc                 C   sZ   | j | jkrd S |   | || jkr2| j|j n
| j|j | j|j | j	 ft
j d S r(   )r   r  r-  r  r   r\   r  r]   rj   r  r   rg   )rT   r   r)   r)   r.   r    s    
zTextInput._handle_releasedc                 C   s   |j |krd S | j}| j}| j}| j}z"|  || j |j	\}}W 5 |  X ||||j
 | jd  }	|	| _||j krd S ||kr| jdd d S |  }
||kr|
| _n||kr|
| _|   |   |   d S )Nr9   r  r  )r   r  r   r   r   rh   ri   rb   	to_widgetrm   rk   r  r  r  r  r   r   r-  r  r	  )rT   r   rd   Z
get_cursorhandle_righthandle_leftr  r\   r]   r  rP  r)   r)   r.   r    s:    


zTextInput._handle_movec                 O   sN  | j s
d S |dd}| j}| j}|r|| j}| j|ddi}|d |jd  |_t| j	d t
| j| j	d  |d | |_|d d	krd S | jd
}|sd S tj| j | j}	|	sd S |d j}
| j|
ddi|	_|	 j|	j8  _|	 j|	j8  _| j}|d }|jd |jd f}| j|ddi\}}||jd  |_||j |_d S )Nrx   bothr  Tr   r9   rn  r8   r|   	selectionr   )r'  r   r  r   
cursor_posr  rK  r\   rY  r   r  r  rj   rN   Z	get_groupr   rg   r   r   rm   r]   r   r   )rT   r*   r+   rx   lhr  Zhp_midrm   r5  r  Zhp_leftr  Z	last_rectZhp_rightr\   r]   r)   r)   r.   r    sB    


zTextInput._position_handlesc                 C   s>   |pt j}|d krd S || j || j || j d S r(   )r   rg   r   r   r   r   rT   r  r)   r)   r.   rC  .  s    
zTextInput._hide_handlesc                 C   s  | j r| jsd S tj}| j}| j}| jd krt| j| |ddd | _}|j| j	| j
| jd t| j| |ddd | _}|j| j	| j
| jd n| jjr|   d S | jsd S |   | j| jkrd | j_| j_|j| jdd |j| jdd tdd	d
}|| j || j d S )Nr  r  )r  rK   rg   r  r   r  r   rR   r  r8   g?r   )r  r'  r   rg   r   r   rH   handle_image_leftr   r  r  r  handle_image_rightrf   r  r	  r  r  r   r   r   r   )rT   r   r  r  r  r   r)   r)   r.   r
  6  sR    
zTextInput._show_handlesr   c                    sr   j s
dS  j}|dkrZt d  _} d j|d  fdd} j||d n|  jsndS |rvdS  j j	 }	}
|\}}|r||fn
 
||}|j}|d d	 }j}|d |d
 td f}|d | dk r8|d
 |d
 |d
  kr$||d
 |	|
 td  f}d|_n||d
 f}d|_n|d | |d kr|d
 |d
 |d
  kr|d | |d
 |	|
 td  f}d|_n|d | |d
 f}d|_nH|d
 |d
 |d
  kr|d |d
 |	|
 td  f}d|_nd|_ j|ddi}|d |_|jd dkr.|d
 |_n
|d
 |_||_t| d|_j|dd td
dd| dS )z-Show a bubble with cut copy and paste buttonsN)rE   rf   Tc                     s
     S r(   )r   r   r  r)   r.   hide_m  s    z-TextInput._show_cut_copy_paste.<locals>.hide_)r   r  r          @r8   g      ?Ztop_leftZbottom_leftZ	top_rightZbottom_rightZtop_midZ
bottom_midr  trR   r  r   r   )
use_bubbler   ru   r  r  r   r   rf   r  r  Z	to_windowr   r   Z	arrow_posr  Zcenter_xrj   r]   rx   r   Z
cancel_allr   r   r   )rT   rm   r  Zparent_changedrx   Zpos_in_windowrC   bubbler  r  Zlsr\   r]   Zt_posZbubble_sizeZ	bubble_hwZwin_sizeZ
bubble_posr)   r  r.   r  a  sj    




zTextInput._show_cut_copy_pastec                 C   s   | j }|sd S |  d S r(   )r   r   )rT   r  r  r)   r)   r.   r     s    zTextInput._hide_cut_copy_pastec                 C   s   | t krt |  dS )z$called when the textinput is deletedN)r?   r@   )rD   r)   r)   r.   r    s    z!TextInput._reload_remove_observerc                 G   sf   t j}|   | | |rN| js(| jr6trF| jdkrF|   d| _	qbd| _	n| j
  | | d S )Nr   TF)r   rg   r  r   r   r   r   r   r  r   r   r   rC  )rT   r   r   largsr  r)   r)   r.   r    s"    

zTextInput._on_textinput_focusedc                 C   s   t sddlm a ma d S )Nr   )r   r  )r   Zkivy.core.clipboardr  r   r)   r)   r.   r     s    zTextInput._ensure_clipboardc                 C   s   |  | j dS )zn Copy current selection to clipboard then delete it from TextInput.

        .. versionadded:: 1.8.0

        N)r   r   r   r)   r)   r.   r     s    zTextInput.cutc                 C   s   |    t| |   d S r(   )r   r   r   rg  rT   datar)   r)   r.   r     s    
zTextInput._cutc                 C   s,   |    |rt|S | jr(t| jS dS )a    Copy the value provided in argument `data` into current clipboard.
        If data is not of type string it will be converted to string.
        If no data is provided then current selection if present is copied.

        .. versionadded:: 1.8.0

        N)r   r   r   r   r  r)   r)   r.   r     s
    
zTextInput.copyc                 C   s&   |    t }|   | | dS )z Insert text from system :class:`~kivy.core.clipboard.Clipboard`
        into the :class:`~kivy.uix.textinput.TextInput` at current cursor
        position.

        .. versionadded:: 1.8.0

        N)r   r   r   rg  rV  r  r)   r)   r.   r     s    zTextInput.pastec                 G   s   t | j d S r(   )r  Zset_cutbufferr   rT   r*   r)   r)   r.   r    s    zTextInput._update_cutbufferc                 C   s   |   }zd|| j|}W n$ tk
r@   d|| j|}Y nX td|}|rT|S |s^| j}|dd| }| js||d }n|| jt	| d }t
d|| |S )zAReturn the width of a text, according to the current line optionsz{} {} {}r7   	r<  r   )_get_line_optionsformatr   UnicodeDecodeError	Cache_getr   rB  get_extentsr   r  Cache_append)rT   r'  r   r   kwcidrK  r)   r)   r.   r"    s(    
zTextInput._get_text_widthc                 C   s   |    dS )z:trigger blink event reset to switch blinking while focusedN)r  r   r)   r)   r.   on_cursor_blink  s    zTextInput.on_cursor_blinkc                 C   s0   | j s"| jjr| j  d| _d S | j | _d S NF)cursor_blinkr   Zis_triggeredr   _cursor_blinkrT   r   r)   r)   r.   r      s    
zTextInput._do_blink_cursorc                 G   s   | j   d| _|    d S r  )r   r   r  r   r)   r)   r.   r  -  s    
zTextInput._reset_cursor_blinkc                 C   s   | j r|   |   dS )zz
        When the cursor is moved, reset cursor blinking to keep it showing,
        and update all the graphics.
        N)r   r  r  r   r)   r)   r.   	on_cursor2  s    zTextInput.on_cursorc                 C   sB   |t | jk st| j| | j| | j| | j| _dS )z,Delete current line, and fix cursor positionN)r  r  AssertionErrorr   rh   r   r  )rT   idxr)   r)   r.   rq  ;  s
    zTextInput._delete_linec                 C   s   |  || j|< || j|< dS )z6Set current line with other text than the default one.N)_create_line_labelr   r  )rT   line_numr'  r)   r)   r.   rJ  C  s    zTextInput._set_line_textc                 G   s2   | j d k	r| j   nt| jd| _ |    d S Nr   )r   r   r	   r   _refresh_line_optionsrT   r  r)   r)   r.   r  H  s    
 z'TextInput._trigger_refresh_line_optionsc                 G   s4   d | _ |   |   |   | t| j| _d S r(   )r   r  rM  rB   r+  r  r'  r  r  r)   r)   r.   r  P  s
    zTextInput._refresh_line_optionsc                    sF   t  r d krd jd k	r,j  t fdd_d S )Nr   r)   c                    s
   j   S r(   rM  r  r  rT   r)   r.   r_   ]  r`   z1TextInput._trigger_refresh_text.<locals>.<lambda>)r  r   r   r	   r  r  r)   r  r.   rA   W  s    

zTextInput._trigger_refresh_textc                 G   s   t d |   d S )Nr7   )r>   rA   r  r)   r)   r.   r  _  s    zTextInput._update_text_optionsc                 G   s   | j |  d S r(   r  )rT   r   r  r)   r)   r.   _refresh_text_from_triggerc  s    z$TextInput._refresh_text_from_triggerc                 G   s   | j | jf|  d S r(   )_refresh_textr'  r  r)   r)   r.   rM  f  s    z%TextInput._refresh_text_from_propertyc              	   G   sP  d}t |dkr&|\}}}}}}d}	n|  }	| |\}| _g }
g }| j}|D ](}||}|
| |t|jd qP|dkr|
| _|| _	|| j
dd< nN|dkr||kr| ||d ||||
| n"|dkr| ||d ||||
| | jdd }t|
d j|| _| j}| |	dkr*|  n|	| _| j|krDd| _|   dS )	z
        Refresh all the lines from a new text.
        By using cache in internal functions, this method should be fast.
        allr8   Nr   r   r=  r1   r   )r  r  rX  r   r  ro   r   r   r   r   r  _insert_linesr   r  rY  r  r  r  r+  r  r  r  )rT   r'  r  rx   r   rS  r  r   rU  r  r   _line_rects_create_labelr\   lblZmin_line_htr$  r)   r)   r.   r  i  sP    
    zTextInput._refresh_textc                 C   s  | j }g }	|	|d |  |r:|r0|| |d< |	| |	||d   |	| _ g }
|
| jd |  |rx|
| |
| j|d   |
| _g }|| jd |  |r|| || j|d   || _g }|| jd |  |r|| || j|d   || jd d < d S r  )r   extendr   r   r  )rT   r   rS  rU  r   r  r   r  Zself_lines_flagsZ_lins_flagsZ
_lins_lblsZ
_lins_rctsZ_linsr)   r)   r.   r    s6    



zTextInput._insert_linesc                 G   s   | j   |    d S r(   )r   r   r  r)   r)   r.   r    s    
z"TextInput._trigger_update_graphicsc                 G   s  | j   | j}|| j }| j}| j}| jrD| jd sXt| jdkrX| j}| j	}| j
}n| j}| j}| j}| j\}	}
}}| j|	 }| j|
 | }| j| }| j|
 }| j}| j}|dko|od|k}d}|df}t|D ]|\}}||  k r|| k r4n n6|dkr|}| |||| ||||||||||}n||krL|d8 } qV||8 }q|dk	rp||d f| _nd| _|   dS )zS
        Update all the graphics according to the current internal values.
        r   r8   r  r  Nr   )rN   clearr  r  r  r  r  r  r   r   _hint_text_linesr   r   r   r\   rj   r]   r   r   r(  
_draw_liner  r.  )rT   r  r  r  r  r  r  r  r  r  r  r  r  r\   r]   minyr  r   r  r  Zfst_visible_lnviewport_posr  r   r)   r)   r.   r     sl    








zTextInput._update_graphicsc           %      C   sP  t |j}|jd d  }| j\}}}}| j| | }| j| | }|\}}|dd  \}}\}}|r|\}}|| | }|| | }nd\}}|d|  |k r|| }|| }n||k r|| | }|}||k r|| | }|}|	|kr||	 | }|| | }|| }|}|	| |k rJ||	|  }|	|7 }	|| }|| | }|}|dk rX|	S ||| f}|| || f} || |f}!||f}"||  |! |" }d}#|
st| }
| _|
r|dkrd|
k}|dkrt	|| d }#n"|d	ks|rt
dt	|| }#|| }$t	|#| t	|	| f|$_||f|$_||$_||$_| j|$ |	S )
Nr8   rn  r   r   r  r  r  r  r  )rt  r   Z
tex_coordsr   rK  r  r   Zfind_base_directionr  r   rY  rm   texturerN   add)%rT   r   r  r'  r&  r  r%  r  r\   r]   r  r   r  r  r   Z	texcoordsr  r  r  r  r  viewport_heightZtexture_widthZtexture_heightZoriginal_heightZoriginal_widthZtchZtcwZtcxZtcyZdiffZtop_left_cornerZtop_right_cornerZbottom_right_cornerZbottom_left_cornerZxoffsetrectr)   r)   r.   r$  	  s|    





zTextInput._draw_linec                  C   s~  | j s
d S | j\}}}}| j}| j}| j}| j}| j}	| j}
| j}| j	}| j
j}| j}t| j| jf\}}||\}}||\}}| j| j }| j}|	| | j ||  }| j}| j| }|	| | }| j
d t| j| }t| j| | | }|||  }tt|t||t|d |d t||dD ]:\}}||j|j|||f||f||
|||||||| q4|  d d S )Nr  r8   )r   r  )!r   r   r   r   r  r   rj   r"  r+  _draw_selectionrN   r(  selection_colorr  r   r   r  r  r\   r  rK  r]   Zremove_groupmathfloorceilr(  r   rY  r  rm   r   r  ) rT   r  r  r  r  r  r  r  r   rj   r  r+  Zdraw_selection
canvas_addr,  r  r  selection_start_colselection_start_rowselection_end_colselection_end_rowr  r\   r]   rK  r%  r  Zfirst_visible_lineZlast_visible_linewidth_minus_paddingr  r*  r)   r)   r.   r.  z	  sh    
z$TextInput._update_graphics_selectionc                 C   s  |\}}|\}}||  kr$|ks*n d S |\}}|\}}|}|| }||krx|| }|| j 8 }|||d | ||	7 }||kr|| }|| j  ||d | ||	 }t||||
 }t||||
 }||krd S |t|ddi |t||f|| |fdd d S )Nr5  r  )rm   r   r5  )r  r   r   r   )rT   rm   r   r  Zselection_startZselection_endr  r  r   r  r5  r  r  r\   r0  r,  r1  r2  r3  r4  r]   whbegr/  r  r)   r)   r.   r+  	  sF    




zTextInput._draw_selectionc                 C   s    |    |   d | _| _d S r  )rA   rB   r  r  r   r)   r)   r.   on_size	  s    zTextInput.on_sizec                 C   s    | j }|t|k r|| jS dS r  )r   r  rK  )rT   r$  Z_labelsr)   r)   r.   r  	  s    
zTextInput._get_row_widthc                 C   s  | j | j }| jd }| jd }| jd }| j| }| j| }|| j }|| j| 8 }| j}| j| | }	| 	 }
| j
p|| j}|dko|od|k}|dkr| | j}|td|	| d  |
 | j }nD|dks|r| | j}|td|	|  |
 | j }n||
 | j }||fS )Nr   r8   r9   r  r  r  r  )r  r  r   r\   rj   r  r  r   rK  r&  r   r  r  rY  r  )rT   r  r  r  r  leftrj   r]   r   r  r&  r  r  	row_widthr\   r)   r)   r.   _get_cursor_pos
  sF    





zTextInput._get_cursor_posc                 C   sh   t t| j\}}| j| jd  }| j| jd  }| j}||krP|t|||  S t|td|| S d S )Nr8   rn  r   )	mapr   r  rj   r   r]   r  r  rY  )rT   r1   cymax_yZmin_yr  r)   r)   r.   _get_cursor_visual_height(
  s    z#TextInput._get_cursor_visual_heightc                 C   s.   t t| j\}}| j| jd  }|t||gS )Nrn  )r=  r   r  rj   r   r  )rT   Zcxr>  r?  r)   r)   r.   _get_cursor_visual_pos4
  s    z TextInput._get_cursor_visual_posc                 C   sJ   | j d krD| j| j| j| j| j| jdddddd | _ }tf || _| j S )Nr:  rj   r   r   )r   r   r   r   r   r   Zanchor_xZanchor_y	padding_x	padding_yr   )	r   r   r   r   r   r   r   r   r   )rT   r  r)   r)   r.   r  :
  s    
zTextInput._get_line_optionsc           
      C   s>  | dd dd| j }| jr2|s2| jt| }|  }d|t|f }td|}|d kr:d }t|}d }	|stj	dd}t
d|| |S zNtf d	|d | i|}|  |	d k	r|	d
kr|	d
 }	||	7 }nW q(W q   |	d krt|}	|	d
 }	|	d
k r|r|d8 }||	8 }Y qY qX q|j}t
d|| |S )Nr1  r   r  r<  z%s %sr4   )r8   r8   r  r'  r9   r8   )rB  r   r   r   r  r  strr  r   creater  r   Zrefreshr'  )
rT   r'  hintZntextr  r	  r'  labelZ	label_lenZldr)   r)   r.   r  M
  s@    




zTextInput._create_line_labelz	 .,:;!?	c                 c   s   |d krd S | j }d}d}t|D ]x\}}||kr|dkrf|dkr||kr||k r`||| V  |}n0||k r|||| V  |||d  V  |d }|}q"||d  V  d S )Nr   r   r1  r8   )_tokenize_delimitersr(  )rT   r'  r  Z	old_indexZ	prev_charr  charr)   r)   r.   	_tokenize
  s$    zTextInput._tokenizec              
   C   s`  | j r| js6|d}dgtgt|d   }||fS d }}g }g }g }dj}|j|j }}	| jd }
| jd }| j|
 | }| j	}| j
| j }}i }| |D ]}|dk}z|| }W n( tk
r   ||||}|||< Y nX || |kr| s|r||| |	| d}g }d}|r.|tO }q|dkr ||kr ||krd }}|D ]b}z|| }W n* tk
r   ||||}|||< Y nX || |kr q||7 }|d7 }qX||  krdkrn nq||d|  |	| t}||d }||8 }qB|}|| q||7 }|| q|sD|t@ rX||| |	| ||fS )z
        Do a "smart" split. If not multiline, or if wrap is set,
        we are not doing smart split, just a split on line break.
        Otherwise, we are trying to split as soon as possible, to prevent
        overflow on the widget.
        r1  r   r8   r   r9   N)rD  do_wrapsplitr  r  rW  ro   r   rK  r"  r   r   rJ  KeyErrorFL_IS_WORDBREAK)rT   r'  r  rT  r\   r  r  Z_joinZlines_appendZlines_flags_appendr  r  rK  
text_widthZ
_tab_widthr   Zwords_widthswordZ
is_newliner6  Zsplit_widthZ	split_poscZcwr)   r)   r.   rX  
  sv    	




zTextInput._split_smartc           
      C   s  |\}}}}| j r2|dkr2|dks(| jr2|   n@|dkrb| j}| d || jkrr| jdd n|dkrr|   |d kr| | n|dkr| j s|   | _| _	d| _ d	| _
n|d
krd| _n|dkrd| _n|dkrd| _n|dkrd| _n|drZ| j\}}	| || jp| j| jp(| j | j rP| j
sP|  | _	|   n|   nH|dkr| jrx| d n| d | jrd	| _n|dkrd	| _d S )N)Nr   r   r   r   r   r   r  r   shiftr   r   TFr   r   r   r   Zcursor_r1  r   escape)r   rD  rg  r  r  re  rV  r  r   r   r   r   r   r   r   r  r-  r  r  text_validate_unfocusr   )
rT   keyrepeatdisplayed_strinternal_strinternal_actionscaler  r  r  r)   r)   r.   	_key_down
  sf    









zTextInput._key_downc                 C   sh   |\}}}}|dkr&| j rd| d n>|dkr6d| _n.|dkrFd| _n|dkrVd| _n|dkrdd| _d S )NrR  Tr   Fr   r   r   )r   r-  r   r   r   r   )rT   rV  rW  rX  rY  rZ  r[  r)   r)   r.   _key_up+  s    zTextInput._key_upc                    s  |\}}t j}t|ddh }|dhkp4to4|dhk}|| j k}	| js`t ||||r`dS |rx|rx|	sx| 	| n| j
r\|r\|	s\| | | | || j t|d }
|s|
dkrd| _d| _|s|
d	krd
| _| jdd  | _| jr|  j|7  _d S | j}|r0|
d	kr0| | d S t jjr>d S | jrN|   | | d S |	rv| | | | |dkrd
| _dS |dkr|   | d dS | j|}|rd d |df}| | d S )NZcapslockZnumlockZctrlmetaTr   r8   r   r9   F   	   r  )r   rg   set_is_osxr  keys	write_tabrI   keyboard_on_key_down_handle_shortcutr   rC  r   r   r   ordr   r   _handle_commandZmanaged_textinputr   rg  rV  r   r   r\  )rT   rg   keycoder'  	modifiersrV  r1   r  Zis_shortcutZis_interesting_key
first_charr   krU   r)   r.   re  9  sh    










zTextInput.keyboard_on_key_downc                    s   d}| d\}}d _ jr&   |dkrzt|}|sF jdd   }t|| d _| _d _ jdd d S |dkr 	|| nj|dkrd	} 	|| nP|d
kr 
d n<|dkr|dkrt fdd n|dkrt| jf _d S )NT:r   ZDELrc  r   ZINSERTZINSERTNFZSELWORDr   ZSEL0c                    s      S r(   )r  r  r   r)   r.   r_     r`   z+TextInput._handle_command.<locals>.<lambda>ZCURCOL)rL  r   r   rg  r   r  rY  r   r   rV  r  r	   r  r  r  )rT   commandrO  r  r*  r/  r)   r   r.   rh    s6    zTextInput._handle_commandc                 C   s   |t dkr|   n|t dkr*|   | js4d S |t dkrN| | j n@|t dkrd|   n*|t dkrz|   n|t dkr|   d S )Nr  rQ  r\   vzr)	rg  r   r   r   r   r   r   ro  rm  )rT   rV  r)   r)   r.   rf    s    


zTextInput._handle_shortcutc                 C   s2   |d }| j |}|r.d d |df}| | d S r  )r  r   r]  )rT   rg   ri  rV  rl  r)   r)   r.   keyboard_on_key_up  s
    zTextInput.keyboard_on_key_upc                 C   s   | j r|   | |d d S r  )r   rg  rV  )rT   rg   r'  r)   r)   r.   keyboard_on_textinput  s    zTextInput.keyboard_on_textinputT)	allownonec                    s   t    tj| jd d S N)Zon_textedit)rI   _bind_keyboardr   r   window_on_texteditr   rU   r)   r.   rw    s    
zTextInput._bind_keyboardc                    s   t    tj| jd d S rv  )rI   _unbind_keyboardr   Zunbindrx  r   rU   r)   r.   ry    s    
zTextInput._unbind_keyboardc                 C   s  | j p
dg}| jr| j\}}|| }t| j}||| | | jkr|d ||  ||d   }|  }	| jd| ||  | |	| | _| r| j	r| 
  | j\}
}|| }|d |
 | ||
d   }| jd| ||  | |  t| | _|| _| j| _d S )Nr   r=  )r=  )r=  )r  rp  _ime_cursorr  r  rM  rL  r+  r  r   rg  )rT   rg   Z	ime_inputZ
text_linesZpccZpcrr'  Zlen_imeZremove_old_ime_textra  r  r  rR  r)   r)   r.   rx    s<    

 

 
zTextInput.window_on_texteditc                 C   s   |    d S r(   )rB   r   r)   r)   r.   on__hint_text  s    zTextInput.on__hint_textc                 C   sx   |  | j\}| _g }g }| j}|D ],}||dd}|| |t|jd q$|| jd d < || _|| _	| 
  d S )NT)rF  r  )rX  	hint_textr   r  ro   r   r   r#  r   r   r  )rT   r  r   r   r  r\   r   r)   r)   r.   rB     s    
zTextInput._refresh_hint_textz
^-?[0-9]*$z^-?[0-9]*\.?[0-9]*$r  )r   *c                 C   s   | j S r(   r   r   r)   r)   r.   _get_cursor]  s    zTextInput._get_cursorc                 C   st   | j s|   d S | j }t|d dt|d }t|d dt|| }||f}| || | j|krjd S || _dS )Nr8   r   T)r  rA   r   r  _adjust_viewportr   )rT   rm   rC   r  r  r  r)   r)   r.   _set_cursor`  s    
zTextInput._set_cursorr   r5   c                 C   s:  | j d }| j d }| j| | }| j}| jp2| j}| jdkoH|oHd|k}|  }	| | j}
|	| |krv|	| | _n|	|d k r|	| _|
| }| j	s|	|kr| j|kr| jdks| jdks|rt
d|| _| j| j }|| }| j d }| j d }| j| | | }| j}||| kr&|| | _n||k r6|| _d S )	Nr   r9   r  r  r8   r  r  rn  )r   rK  r  r   r  r   r&  r  r  rD  rY  r  r  r  r  )rT   r  r  r  r  r  Zsxr  r  r#  r;  Zviewport_scroll_xr  Zoffsetyr  r  r)  Zsyr)   r)   r.   r  s  sP    






zTextInput._adjust_viewportc                 C   s
   | j d S r  r~  r   r)   r)   r.   _get_cursor_col  s    zTextInput._get_cursor_col)r  c                 C   s
   | j d S )Nr8   r~  r   r)   r)   r.   _get_cursor_row  s    zTextInput._get_cursor_row)	r  r   rm   r   r   r  r  r  r  )r   cacher8   r   Z1spr  r9   )length
deprecatedc                 C   s    |d | j d< |d | j d< d S )Nr   r8   r9   r   r   r)   r)   r.   on_padding_x  s    zTextInput.on_padding_xc                 C   s    |d | j d< |d | j d< d S )Nr   r8   rn  r  r   r)   r)   r.   on_padding_y  s    zTextInput.on_padding_yr  r  r:  r  r  )optionsgSt$?gD?gF%u?rw   z*atlas://data/images/defaulttheme/textinputz3atlas://data/images/defaulttheme/textinput_disabledz1atlas://data/images/defaulttheme/textinput_activec                 C   s   | j S r(   )r   r   r)   r)   r.   get_sel_from  s    zTextInput.get_sel_fromc                 C   s   | j S r(   )r   r   r)   r)   r.   
get_sel_to  s    zTextInput.get_sel_toc                 C   s(   |r$| j r|   tr$| js$|   d S r(   )r  r  r  r   r  r   r)   r)   r.   on_selection_text  s
    
zTextInput.on_selection_textc                    s\   | j  | jt}t |k }|r. d d fddt|D }|rX   |S )Nr8   r   c                 3   s*   | ]"} | t @ rd nd|  V  qdS )r1  r   N)r  )r  r)  r  r  r)   r.   r    s   z&TextInput._get_text.<locals>.<genexpr>)r   r  r  ro   rW  r  rh   )rT   rU  Z
less_flagsr'  r)   r  r.   	_get_text  s    
zTextInput._get_textc                 C   sN   t |tr|d}| jr&|dd}| j|krJ| | | t|| _	d S )Nr9  r:  r1  )
r>  r?  r@  rA  rB  r'  r  r+  r  r  )rT   r'  r)   r)   r.   	_set_text  s    



zTextInput._set_text)r  Z15spZltrr  Zweak_rtlZweak_ltr)r  ru  c                 C   s   t |tr|d}|| _d S )Nr9  )r>  r?  r@  
_hint_text)rT   r   r)   r)   r.   _set_hint_text  s    

zTextInput._set_hint_textc                 C   s   | j S r(   r  r   r)   r)   r.   _get_hint_text  s    zTextInput._get_hint_textr  g      ?c                 C   s*   t | j| j| j  | jd  | jd  S )Nr8   rn  )r  r  r  r  r   r   r)   r)   r.   _get_min_height  s    zTextInput._get_min_height)	r  r  r   r   r   r   r   r|  r  rn  )r  z0atlas://data/images/defaulttheme/selector_middlec                 C   s   | j r|| j _d S r(   )r   r  r   r)   r)   r.   on_handle_image_middle.  s    z TextInput.on_handle_image_middlez.atlas://data/images/defaulttheme/selector_leftc                 C   s   | j r|| j _d S r(   )r   r  r   r)   r)   r.   on_handle_image_left<  s    zTextInput.on_handle_image_leftz/atlas://data/images/defaulttheme/selector_rightc                 C   s   | j r|| j _d S r(   )r   r  r   r)   r)   r.   on_handle_image_rightK  s    zTextInput.on_handle_image_right)N)F)NN)Frb  )N)N)N)N)NNF)FF)FF)F)F)r  )N)Fr   F)N)r   )F)F)F)rq   rr   rs   __doc__Z
__events__r  rJ   r   r  r&  r+  r0  r   rG  compiler3  r8  rV  rL  rN  r   rm  ro  re  rr  ru  ry  r{  r  r|  rf  propertyr  r  r  r  r  r  rg  r  r-  r  r  r  r   r   r   rp   r  r  r   r  r  r  r  r  rC  r
  r  r   staticmethodr  r  r   r   r   r   r   r  r"  r
  r   r  r  rq  rJ  r  r  rA   r  r  rM  r  r  r  r   r$  r.  r+  r9  r  r<  r@  rA  r  r  rH  rJ  rX  r\  r]  re  rh  rf  rs  rt  r   rp  r"   rz  rw  ry  rx  r{  rB   r  r#  r   r   rH  rI  r  r    Z_cursor_visual_posZ_cursor_visual_heightr   rU  rD  rK  r   r   r  r  r  r3   r  r  r  r!  r  r  r  r%   Zcursor_colorr   Zcursor_widthr  r   r$   rB  r  rC  r  r   r!   r   r  r  r,  ZborderZbackground_normalZbackground_disabled_normalZbackground_activeZbackground_colorZforeground_colorZdisabled_foreground_colorr   r  r  r  _scroll_distancer=   r  r<   r  r  r  r  r   r  r  r  r'  r   r   r   r   r   r   r   r  r  r  r|  Zhint_text_colorrE  rA  r   r  r  r  r&   r  r#   rF  r  r  r  r  r  r  rd  rt   r)   r)   rU   r.   r'     s  <}
F 
%'8
&'
    
c
w<
'	Q2/&',    
P
	5$Pd><&3ODK

    		
	
3
		
	

	
	


	
		
  				
r'   __main__)dedent)App)	BoxLayout)Builderu  
    #:set font_size '20dp'

    BoxLayout:
        orientation: 'vertical'
        padding: '20dp'
        spacing: '10dp'
        TextInput:
            font_size: font_size
            size_hint_y: None
            height: self.minimum_height
            multiline: False
            text: 'monoline'

        TextInput:
            size_hint_y: None
            font_size: font_size
            height: self.minimum_height
            multiline: False
            password: True
            password_mask: '•'
            text: 'password'

        TextInput:
            font_size: font_size
            size_hint_y: None
            height: self.minimum_height
            multiline: False
            readonly: True
            text: 'readonly'

        TextInput:
            font_size: font_size
            size_hint_y: None
            height: self.minimum_height
            multiline: False
            disabled: True
            text: 'disabled'

        TextInput:
            font_size: font_size
            hint_text: 'normal with hint text'

        TextInput:
            font_size: font_size
            text: 'default'

        TextInput:
            font_size: font_size
            text: 'bubble & handles'
            use_bubble: True
            use_handles: True

        TextInput:
            font_size: font_size
            text: 'no wrap'
            do_wrap: False

        TextInput:
            font_size: font_size
            text: 'multiline\nreadonly'
            disabled: app.time % 5 < 2.5
    c                   @   s"   e Zd Ze Zdd Zdd ZdS )TextInputAppc                 C   s   t | jd ttS r  )r	   ry   update_timer  load_stringKVr   r)   r)   r.   build  s    zTextInputApp.buildc                 C   s   |  j |7  _ d S r(   )timer  r)   r)   r.   r    s    zTextInputApp.update_timeN)rq   rr   rs   r   r  r  r  r)   r)   r)   r.   r    s   r  )ir  rG  sysr-  osr   weakrefr   	itertoolsr   r   Zkivy.animationr   Z	kivy.baser   Z
kivy.cacher   Z
kivy.clockr	   Zkivy.configr
   Zkivy.core.windowr   Zkivy.metricsr   Z
kivy.utilsr   r   Zkivy.uix.behaviorsr   Zkivy.core.textr   r   Zkivy.graphicsr   r   r   r   r   Z"kivy.graphics.context_instructionsr   Zkivy.graphics.texturer   Zkivy.uix.widgetr   Zkivy.uix.bubbler   r   Zkivy.uix.imager   Zkivy.propertiesr   r   r   r    r!   r"   r#   r$   r%   r&   __all__r3   registerZCache_registerro   r  r   r  r@   r>   r  rN  r  r   r  ZMarkupLabel	_platformr?   rb  r   r  r  
getbooleangetintr  rF   Zkivy.graphics.contextrG   Zadd_reload_observerrH   ru   r'   rq   textwrapr  Zkivy.appr  Zkivy.uix.boxlayoutr  Z	kivy.langr  r  r  runr)   r)   r)   r.   <module>   s    0




0                            O
@
