U
    Pe6                     @   s  d Z dZddlZed ddl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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$m%Z%m&Z& ddl'm(Z( ddl)m*Z* ddl+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4 ddl5m6Z6 ddl7m8Z8 ddl9m:Z: e:;d dd Z<G dd deeZ=G dd  d eZ>G d!d" d"eZ?G d#d$ d$eZ@G d%d& d&eZAG d'd( d(eBZCG d)d* d*eCZDG d+d, d,eCZEG d-d. d.eCZFG d/d0 d0eZGG d1d2 d2eCZHG d3d4 d4eCZIG d5d6 d6eeZJG d7d8 d8eZKG d9d: d:eZLG d;d< d<eCZMG d=d> d>eZNd?d@ ZOdAdB ZPdCdD ZQdS )EaS  
Console
=======

.. versionadded:: 1.9.1

Reboot of the old inspector, designed to be modular and keep concerns
separated. It also has an addons architecture that allow you to add a button,
panel, or more in the Console itself.

.. warning::

    This module works, but might fail in some cases. Please contribute!

Usage
-----

For normal module usage, please see the :mod:`~kivy.modules` documentation::

    python main.py -m console

Mouse navigation
----------------

When the "Select" button is activated, you can:

- tap once on a widget to select it without leaving inspect mode
- double tap on a widget to select and leave inspect mode (then you can
  manipulate the widget again)

Keyboard navigation
-------------------

- "Ctrl + e": toggle console
- "Escape": cancel widget lookup, then hide inspector view
- "Up": select the parent widget
- "Down": select the first child of the currently selected widget
- "Left": select the previous sibling
- "Right": select the next sibling

Additional information
----------------------

Some properties can be edited live. However, due to the delayed usage of
some properties, it might crash if you don't handle the required cases.

Addons
------

Addons must be added to `Console.addons` before the first Clock tick of the
application, or before :attr:`create_console` is called. You currently cannot
add addons on the fly. Addons are quite cheap until the Console is activated.
Panels are even cheaper as nothing is done until the user selects them.

We provide multiple addons activated by default:

- ConsoleAddonFps: display the FPS at the top-right
- ConsoleAddonSelect: activate the selection mode
- ConsoleAddonBreadcrumb: display the hierarchy of the current widget at the
  bottom
- ConsoleAddonWidgetTree: panel to display the widget tree of the application
- ConsoleAddonWidgetPanel: panel to display the properties of the selected
  widget

If you need to add custom widgets in the Console, please use either
:class:`ConsoleButton`, :class:`ConsoleToggleButton` or :class:`ConsoleLabel`.

An addon must inherit from the :class:`ConsoleAddon` class.

For example, here is a simple addon for displaying the FPS at the top/right
of the Console::

    from kivy.modules.console import Console, ConsoleAddon

    class ConsoleAddonFps(ConsoleAddon):
        def init(self):
            self.lbl = ConsoleLabel(text="0 Fps")
            self.console.add_toolbar_widget(self.lbl, right=True)

        def activate(self):
            self.event = Clock.schedule_interval(self.update_fps, 1 / 2.)

        def deactivated(self):
            self.event.cancel()

        def update_fps(self, *args):
            fps = Clock.get_fps()
            self.lbl.text = "{} Fps".format(int(fps))

    Console.register_addon(ConsoleAddonFps)


You can create addons that add panels. Panel activation/deactivation is not
tied to the addon activation/deactivation, but in some cases, you can use the
same callback for deactivating the addon and the panel. Here is a simple
"About" panel addon::

    from kivy.modules.console import Console, ConsoleAddon, ConsoleLabel

    class ConsoleAddonAbout(ConsoleAddon):
        def init(self):
            self.console.add_panel("About", self.panel_activate,
                                   self.panel_deactivate)

        def panel_activate(self):
            self.console.bind(widget=self.update_content)
            self.update_content()

        def panel_deactivate(self):
            self.console.unbind(widget=self.update_content)

        def deactivate(self):
            self.panel_deactivate()

        def update_content(self, *args):
            widget = self.console.widget
            if not widget:
                return
            text = "Selected widget is: {!r}".format(widget)
            lbl = ConsoleLabel(text=text)
            self.console.set_content(lbl)

    Console.register_addon(ConsoleAddonAbout)

)startstopcreate_consoleConsoleConsoleAddonConsoleButtonConsoleToggleButtonConsoleLabel    Nz1.9.0)partial)chain)Logger)Widget)Button)ToggleButton)Label)	TextInput)Image)TreeViewNodeTreeView)
GridLayout)RelativeLayout)	BoxLayout)	ModalView)Color	Rectangle
PushMatrix	PopMatrix)	Transform)Matrix)	ObjectPropertyBooleanPropertyListPropertyNumericPropertyStringPropertyOptionPropertyReferenceListPropertyAliasPropertyVariableListProperty)Texture)Clock)Buildera  
<Console>:
    size_hint: (1, None) if self.mode == "docked" else (None, None)
    height: dp(250)

    canvas:
        Color:
            rgb: .185, .18, .18
        Rectangle:
            size: self.size
        Color:
            rgb: .3, .3, .3
        Rectangle:
            pos: 0, self.height - dp(48)
            size: self.width, dp(48)

    GridLayout:
        cols: 1
        id: layout

        GridLayout:
            id: toolbar
            rows: 1
            height: "48dp"
            size_hint_y: None
            padding: "4dp"
            spacing: "4dp"


        RelativeLayout:
            id: content


<ConsoleAddonSeparator>:
    size_hint_x: None
    width: "10dp"

<ConsoleButton,ConsoleToggleButton,ConsoleLabel>:
    size_hint_x: None
    width: self.texture_size[0] + dp(20)


<ConsoleAddonBreadcrumbView>:
    size_hint_y: None
    height: "48dp"
    canvas:
        Color:
            rgb: .3, .3, .3
        Rectangle:
            size: self.size
    ScrollView:
        id: sv
        do_scroll_y: False
        GridLayout:
            id: stack
            rows: 1
            size_hint_x: None
            width: self.minimum_width
            padding: "4dp"
            spacing: "4dp"

<TreeViewProperty>:
    height: max(dp(48), max(lkey.texture_size[1], ltext.texture_size[1]))
    Label:
        id: lkey
        text: root.key
        text_size: (self.width, None)
        width: 150
        size_hint_x: None
    Label:
        id: ltext
        text: [repr(getattr(root.widget, root.key, '')), root.refresh][0]                if root.widget else ''
        text_size: (self.width, None)

<ConsoleAddonWidgetTreeView>:
    ScrollView:
        scroll_type: ['bars', 'content']
        bar_width: '10dp'

        ConsoleAddonWidgetTreeImpl:
            id: widgettree
            hide_root: True
            size_hint: None, None
            height: self.minimum_height
            width: max(self.parent.width, self.minimum_width)
            selected_widget: root.widget
            on_select_widget: root.console.highlight_widget(args[1])

<-TreeViewWidget>:
    height: self.texture_size[1] + sp(4)
    size_hint_x: None
    width: self.texture_size[0] + sp(4)

    canvas.before:
        Color:
            rgba: self.color_selected if self.is_selected else (0, 0, 0, 0)
        Rectangle:
            pos: self.pos
            size: self.size
        Color:
            rgba: 1, 1, 1, int(not self.is_leaf)
        Rectangle:
            source:
                ('atlas://data/images/defaulttheme/tree_%s' %
                ('opened' if self.is_open else 'closed'))
            size: 16, 16
            pos: self.x - 20, self.center_y - 8

    canvas:
        Color:
            rgba:
                (self.disabled_color if self.disabled else
                (self.color if not self.markup else (1, 1, 1, 1)))
        Rectangle:
            texture: self.texture
            size: self.texture_size
            pos:
                (int(self.center_x - self.texture_size[0] / 2.),
                int(self.center_y - self.texture_size[1] / 2.))

c                    s    fdd}|S )Nc                     s   z | |W S    Y nX d S N )argskwargsfr,   8/tmp/pip-unpacked-wheel-xzebddm3/kivy/modules/console.pyf2  s    zignore_exception.<locals>.f2r,   )r0   r2   r,   r/   r1   ignore_exception  s    r3   c                   @   sB   e Zd ZedddZedZedddZdd Ze	edddZ
dS )	TreeViewPropertyNTZ	allownoneFc                 C   s.   | j }|d krd S | }|d kr*d | _ d S |S r+   
widget_ref)selfwrr,   r,   r1   _get_widget+  s    zTreeViewProperty._get_widgetr6   )bind)__name__
__module____qualname__r   keyr    Zrefreshr7   r:   r&   widgetr,   r,   r,   r1   r4   &  s
   
r4   c                   @   s   e Zd ZdZdS )r   z"Button specialized for the ConsoleNr<   r=   r>   __doc__r,   r,   r,   r1   r   8  s   r   c                   @   s   e Zd ZdZdS )r   z(ToggleButton specialized for the ConsoleNrA   r,   r,   r,   r1   r   =  s   r   c                   @   s   e Zd ZdZdS )r   z'LabelButton specialized for the ConsoleNrA   r,   r,   r,   r1   r   B  s   r   c                   @   s   e Zd ZdS )ConsoleAddonSeparatorN)r<   r=   r>   r,   r,   r,   r1   rC   G  s   rC   c                       s<   e Zd ZdZdZ fddZdd Zdd Zd	d
 Z  Z	S )r   z"Base class for implementing addonsNc                    s    t t|   || _|   d S r+   )superr   __init__consoleinit)r8   rF   	__class__r,   r1   rE   Q  s    zConsoleAddon.__init__c                 C   s   dS )zDMethod called when the addon is instantiated by the Console
        Nr,   r8   r,   r,   r1   rG   V  s    zConsoleAddon.initc                 C   s   dS )z`Method called when the addon is activated by the console
        (when the console is displayed)Nr,   rJ   r,   r,   r1   activate[  s    zConsoleAddon.activatec                 C   s   dS )zhMethod called when the addon is deactivated by the console
        (when the console is hidden)
        Nr,   rJ   r,   r,   r1   
deactivate`  s    zConsoleAddon.deactivate)
r<   r=   r>   rB   rF   rE   rG   rK   rL   __classcell__r,   r,   rH   r1   r   K  s   r   c                   @   s   e Zd Zdd ZdS )ConsoleAddonModec                 C   s   t dd}| j| d S )NZDockedtext)r   rF   add_toolbar_widget)r8   btnr,   r,   r1   rG   h  s    
zConsoleAddonMode.initN)r<   r=   r>   rG   r,   r,   r,   r1   rN   g  s   rN   c                   @   s$   e Zd Zdd Zdd Zdd ZdS )ConsoleAddonSelectc                 C   s>   t dd| _| jj| jd | j| j | jj| jd d S )NZSelectrO   )state)inspect_enabled)r   rR   r;   on_button_staterF   rQ   on_inspect_enabledrJ   r,   r,   r1   rG   n  s    zConsoleAddonSelect.initc                 C   s   |rdnd| j _d S )Ndownnormal)rR   rT   r8   instancevaluer,   r,   r1   rW   t  s    z%ConsoleAddonSelect.on_inspect_enabledc                 C   s   |dk| j _d S )NrX   )rF   rU   rZ   r,   r,   r1   rV   w  s    z"ConsoleAddonSelect.on_button_stateN)r<   r=   r>   rG   rW   rV   r,   r,   r,   r1   rS   m  s   rS   c                   @   s0   e Zd ZdZdd Zdd Zdd Zdd	 ZdS )
ConsoleAddonFpsNc                 C   s"   t dd| _| jj| jdd d S )Nz0 FpsrO   T)right)r   lblrF   rQ   rJ   r,   r,   r1   rG     s    zConsoleAddonFps.initc                 C   s*   | j }|d kr t| jd| _ n|  d S )Ng      ?)
_update_evr)   schedule_interval
update_fps)r8   Zevr,   r,   r1   rK     s    zConsoleAddonFps.activatec                 C   s   | j d k	r| j   d S r+   )r`   cancelrJ   r,   r,   r1   deactivated  s    
zConsoleAddonFps.deactivatedc                 G   s   t  }dt|| j_d S )Nz{} Fps)r)   Zget_fpsformatintr_   rP   )r8   r-   Zfpsr,   r,   r1   rb     s    zConsoleAddonFps.update_fps)r<   r=   r>   r`   rG   rK   rd   rb   r,   r,   r,   r1   r]   {  s
   r]   c                   @   s,   e Zd ZedddZg Zdd Zdd ZdS )ConsoleAddonBreadcrumbViewNTr5   c           	      C   s   | j j}dd | jD }||krL||}| jD ]
}d|_q0d| j| _d S |  |s\d S |}g }t|jjd}t	
||_|j| jd || ||jkrq|j}qdt|D ]}|| qd| j j_|| _d|_d S )Nc                 S   s   g | ]}|  qS r,   r6   ).0rR   r,   r,   r1   
<listcomp>  s     z8ConsoleAddonBreadcrumbView.on_widget.<locals>.<listcomp>rY   rX   rO   Z
on_release   )idsstackparentsindexrT   clear_widgetsr   rI   r<   weakrefrefr7   r;   highlight_widgetappendparentreversed
add_widgetsvZscroll_x)	r8   r[   r\   rm   Zprefsro   rR   r@   rn   r,   r,   r1   	on_widget  s2    




z$ConsoleAddonBreadcrumbView.on_widgetc                 C   s   |  | j_d S r+   )r7   rF   r@   r8   r[   r,   r,   r1   rs     s    z+ConsoleAddonBreadcrumbView.highlight_widget)r<   r=   r>   r   r@   rn   ry   rs   r,   r,   r,   r1   rg     s   "rg   c                   @   s,   e Zd Zdd Zdd Zdd Zdd Zd	S )
ConsoleAddonBreadcrumbc                 C   s(   t  | _| j| j_| jjj| j d S r+   )rg   viewrF   rl   Zlayoutrw   rJ   r,   r,   r1   rG     s    
zConsoleAddonBreadcrumb.initc                 C   s   | j j| jd |   d S N)r@   rF   r;   update_contentrJ   r,   r,   r1   rK     s    zConsoleAddonBreadcrumb.activatec                 C   s   | j j| jd d S r}   rF   unbindr   rJ   r,   r,   r1   rL     s    z!ConsoleAddonBreadcrumb.deactivatec                 G   s   | j j| j_d S r+   )rF   r@   r|   )r8   r-   r,   r,   r1   r     s    z%ConsoleAddonBreadcrumb.update_contentN)r<   r=   r>   rG   rK   rL   r   r,   r,   r,   r1   r{     s   r{   c                   @   sf   e Zd Zdd Zdd Zdd Zdd ZdddZedd Z	edd Z
edd Zedd Zd	S )ConsoleAddonWidgetPanelc                 C   s   | j d| j| j d S )NZ
Properties)rF   	add_panelpanel_activaterL   rJ   r,   r,   r1   rG     s    zConsoleAddonWidgetPanel.initc                 C   s   | j j| jd |   d S r}   r~   rJ   r,   r,   r1   r     s    z&ConsoleAddonWidgetPanel.panel_activatec                 C   s   | j j| jd d S r}   r   rJ   r,   r,   r1   rL     s    z"ConsoleAddonWidgetPanel.deactivatec              	   G   s  | j j}|sd S ddlm} t  | _}|ddgdd | _}tdd d}|j|	d	d
 t
|  }|  d }t|}	|D ]X}
t|
|	d}|j| jd z"|jf |
t| jt|i W n   Y nX || q|| || | j | d S )Nr	   )
ScrollViewZbarscontentZ10dp)Zscroll_typeZ	bar_widthT)Z	hide_rootsize_hint_yheightZminimum_height)r?   r7   )Zis_selected)rF   r@   Zkivy.uix.scrollviewr   r   rootrx   r   r;   setterlistZ
propertieskeyssortrq   rr   r4   show_propertyr
   Zupdate_node_contentadd_noderw   set_content)r8   r-   r@   r   r   rx   Ztreeviewr   nodeZ	wk_widgetr?   r,   r,   r1   r     s8    
 


z&ConsoleAddonWidgetPanel.update_contentNc                 G   s4  |dkrd S | j }d }|d krDd}|j}	|j}|	|}
t|	|}nd}|}	d }
d }t|
tsb|rt|ttfkrxd}n*t|t	t
fkrd}nt|ttfkrd}t|
ts|dkrtt|pddd}|jt| j|	||d n"t|
ts|dkr&t|pddd}|jt| j|	||d nt|
tsTt|
tsTt|
tsT|dkrtd	d d
}|j|dd t|D ]d\}}tt|d dd}t|tr|jt|j|dd n|jt| j|	|||d || qzn"t|
t rdtd	d d
}|j|dd |
j!D ]L}t"|||kr*dndt|j#d dd}|jt| j$|	|d || qnt|
t%rt|trtt|d}|jt|j|d n&t|t&rt'|d}nt(t|d}n>t|
t)r|rdnd}t"||d}|jt| j*|	||d | j+,  | j+| j- |r0| j+| d S )NFTstringnumericr    )rP   	multilinerO   rk   )colsr   r   r   ,   )rP   r   r   rj   rX   rY   )rP   rT   groupr   r   Zon_press)Ztexture)rP   rT   ).rF   r@   r?   propertygetattr
isinstancer&   typestrrf   floattupler   r"   r   r;   r
   save_property_numericr#   save_property_textr!   r%   r'   r   r   	enumerater   reprr   rs   r   rw   r$   optionsr   uidsave_property_optionr   r(   r   r   r    save_property_booleanr   rp   rx   )r8   r[   r\   r?   ro   lrF   r   nestedr@   propZdtypeiitembuttonoptionrT   r,   r,   r1   r     s    



 
  

 
z%ConsoleAddonWidgetPanel.show_propertyc                 C   s4   |dkrt |jt|||< nt||t |j d S Nr	   )r   rP   r   setattrr8   r@   r?   ro   r[   r\   r,   r,   r1   r   T  s    z-ConsoleAddonWidgetPanel.save_property_numericc                 C   s,   |dkr|j t|||< nt|||j  d S r   )rP   r   r   r   r,   r,   r1   r   [  s    z*ConsoleAddonWidgetPanel.save_property_textc                 C   s2   |j dk}|dkr"|t|||< nt||| d S )NrX   r	   )rT   r   r   r   r,   r,   r1   r   b  s    
z-ConsoleAddonWidgetPanel.save_property_booleanc                 G   s   t |||j d S r+   )r   rP   )r8   r@   r?   r[   r   r,   r,   r1   r   j  s    z,ConsoleAddonWidgetPanel.save_property_option)Nr   )r<   r=   r>   rG   r   rL   r   r   r3   r   r   r   r   r,   r,   r,   r1   r     s   
\


r   c                   @   s   e Zd ZedZdS )TreeViewWidgetN)r<   r=   r>   r   r@   r,   r,   r,   r1   r   o  s   r   c                       sb   e Zd ZedddZdZ fddZdd Zd	d
 Zdd Z	d fdd	Z
dd Zdd Z  ZS )ConsoleAddonWidgetTreeImplNTr5   )on_select_widgetc                    s$   t t| jf | t| j| _d S r+   )rD   r   rE   r)   Zcreate_trigger_update_scrollupdate_scroll)r8   r.   rH   r,   r1   rE   x  s    z#ConsoleAddonWidgetTreeImpl.__init__c              	   C   sH   |   D ]:}|jsqz|j|kr*|W   S W q tk
r@   Y qX qd S r+   )Ziterate_all_nodesparent_noder@   ReferenceErrorr8   r@   r   r,   r,   r1   find_node_by_widget|  s    
z.ConsoleAddonWidgetTreeImpl.find_node_by_widgetc                 C   sH   |rD|  |}|rD| |d |rDt|trD|js<| | |j}qd S )NF)r   select_noder   r   is_openZtoggle_noder   r   r,   r,   r1   update_selected_widget  s    

z1ConsoleAddonWidgetTreeImpl.update_selected_widgetc                 C   s   |r|  | |   d S r+   )r   r   )r8   instr@   r,   r,   r1   on_selected_widget  s    
z-ConsoleAddonWidgetTreeImpl.on_selected_widgetc                    sB   t t| | |r>z| d|jj W n tk
r<   Y nX d S )Nr   )rD   r   r   dispatchr@   __self__r   )r8   r   Zselect_widgetrH   r,   r1   r     s    z&ConsoleAddonWidgetTreeImpl.select_nodec                 C   s   d S r+   r,   r8   r@   r,   r,   r1   r     s    z+ConsoleAddonWidgetTreeImpl.on_select_widgetc                 G   s   | j }|sd S | j| d S r+   )Z_selected_noderu   Z	scroll_to)r8   r-   r   r,   r,   r1   r     s    z)ConsoleAddonWidgetTreeImpl._update_scroll)T)r<   r=   r>   r   Zselected_widgetZ
__events__rE   r   r   r   r   r   r   rM   r,   r,   rH   r1   r   s  s   
r   c                   @   s.   e Zd ZedddZdZd	ddZdd ZdS )
ConsoleAddonWidgetTreeViewNTr5   Fc           	   	   C   s   | j j}g }i }|jd d  D ]2}z|||j< W n tk
rD   Y nX || q|jD ]T}t|trhqX||kr|	|| |}n|	t
|jj|j|d|}|||f qX|S )NrP   r@   r   )rl   
widgettreenodesr@   r   remove_nodechildrenr   r   r   r   rI   r<   Z	proxy_refrt   )	r8   r   r@   r   treeZupdate_nodesr   Zcnodechildr,   r,   r1   _update_widget_tree_node  s.    

z3ConsoleAddonWidgetTreeView._update_widget_tree_nodec                 G   s|   | j j}| js(| jjtd|dd| _| j| j|dd}|rh|d d  }g }|D ]}|| j| 7 }qRq:| jj| j	 d S )NZWindowTr   )r   )
rF   win_window_noderl   r   r   r   r   r   r@   )r8   r-   r   r   Zntmpr   r,   r,   r1   update_widget_tree  s"    
z-ConsoleAddonWidgetTreeView.update_widget_tree)F)r<   r=   r>   r   r@   r   r   r   r,   r,   r,   r1   r     s   
r   c                   @   s4   e Zd Zdd Zdd Zdd Zdd Zd	d
 ZdS )ConsoleAddonWidgetTreec                 C   s"   d | _ | jd| j| j| j d S )NZTree)r   rF   r   r   rL   panel_refreshrJ   r,   r,   r1   rG     s    zConsoleAddonWidgetTree.initc                 C   s   | j j| jd |   d S r}   r~   rJ   r,   r,   r1   r     s    z%ConsoleAddonWidgetTree.panel_activatec                 C   s*   | j rd | j _d | j _| jj| jd d S r}   )r   r@   rF   r   r   rJ   r,   r,   r1   rL     s    z!ConsoleAddonWidgetTree.deactivatec                 G   sD   | j j}| jst | _| j | j_ || j_| j  | j | j d S r+   )rF   r@   r   r   r   r   )r8   r-   r@   r,   r,   r1   r     s    

z%ConsoleAddonWidgetTree.update_contentc                 C   s   | j r| j   d S r+   )r   r   rJ   r,   r,   r1   r     s    z$ConsoleAddonWidgetTree.panel_refreshN)r<   r=   r>   rG   r   rL   r   r   r,   r,   r,   r1   r     s
   	r   c                       s  e Zd ZdZeeeeegZ	e
dddgdZedddZedZedZ fd	d
Zdd Zedd Zd1ddZdd Zd2ddZdd Zdd Z f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!d)d* Z"d+d, Z#d-d. Z$d/d0 Z%  Z&S )3r   zConsole interface

    This widget is created by create_console(), when the module is loaded.
    During that time, you can add addons on the console to extend the
    functionalities, or add your own application stats / debugging module.
    ZdockedZfloated)r   NTr5   Fc              	      s   | dd | _tt| jf | d| _| jj: tdddd| _	t
  tt | _tdd| _t  W 5 Q R X t| jd g g g d| _g | _d | _| jD ]}|| }| j| q|   | jd	 d | _d
| j_| j  d S )Nr   Frk   r	   g      ?r	   r	   )sizeleftpanelsr^   r   rX   )popr   rD   r   rE   avoid_bring_to_topZcanvasbeforer   Zgcolorr   r   r   
gtransformr   grectr   r)   ra   update_widget_graphics_toolbar_addons_paneladdonsrt   _init_toolbarrT   cb_activate)r8   r.   addonr[   rH   r,   r1   rE     s(    

zConsole.__init__c                 C   sX   | j j}dD ]F}|dkr$|t  | j| D ]}|| q.|dkr|t  qd S )Nr   r^   )rl   toolbarrw   r   r   rC   )r8   r   r?   elr,   r,   r1   r   *  s    zConsole._init_toolbarc                 C   s   | j | d S r+   )r   rt   )clsr   r,   r,   r1   register_addon4  s    zConsole.register_addonc                 C   s    |rdnd}| j | | dS )zAdd a widget in the top left toolbar of the Console.
        Use `right=True` if you wanna add the widget at the right instead.
        r^   r   N)r   rt   )r8   r@   r^   r?   r,   r,   r1   rQ   8  s    zConsole.add_toolbar_widgetc                 C   s   | j j| dS )z)Remove a widget from the toolbar
        N)rl   r   remove_widgetr   r,   r,   r1   remove_toolbar_widget?  s    zConsole.remove_toolbar_widgetc                 C   s>   t |d}||_||_||_|j| jd | jd | dS )a  Add a new panel in the Console.

        - `cb_activate` is a callable that will be called when the panel is
          activated by the user.

        - `cb_deactivate` is a callable that will be called when the panel is
          deactivated or when the console will hide.

        - `cb_refresh` is an optional callable that is called if the user
          click again on the button for display the panel

        When activated, it's up to the panel to display a content in the
        Console by using :meth:`set_content`.
        rO   r   r   N)r   r   cb_deactivate
cb_refreshr;   _activate_panelr   rt   )r8   namer   r   r   rR   r,   r,   r1   r   D  s    
zConsole.add_panelc                 C   s`   | j |krB| j   d| j _| jj  || _ | j   d| j _nd| j _| j jr\| j   d S )NrY   rX   )r   r   rT   rl   r   rp   r   r   rz   r,   r,   r1   r   Z  s    



zConsole._activate_panelc                 C   s   | j j  | j j| dS )z4Replace the Console content with a new one.
        N)rl   r   rp   rw   )r8   r   r,   r,   r1   r   g  s    zConsole.set_contentc                    s\   t t| |}d|jks$|jdkrL|sL| jrL| j|j  |jrFd| _d}n| j	|j }|S )Nr   r   FT)
rD   r   on_touch_downZprofiler   rU   highlight_atposZis_double_tapcollide_pointr8   touchretrH   r,   r1   r   m  s    zConsole.on_touch_downc                    s.   t t| |}|s*| jr*| j|j  d}|S NT)rD   r   on_touch_moverU   r   r   r   rH   r,   r1   r   y  s
    
zConsole.on_touch_movec                    s"   t t| |}|s| jrd}|S r   )rD   r   on_touch_uprU   r   rH   r,   r1   r     s    
zConsole.on_touch_upc                 C   s4   | j s| jsd S d| _ ||  ||  d| _ d S )NTF)r   	activatedr   rw   )r8   r   r   r,   r,   r1   on_window_children  s    

zConsole.on_window_childrenc                 C   sj   d}| j j}tdd t|D dd t|D }|D ]$}|| krDq6| |||}|r6 q\q6| | dS )z{Select a widget from a x/y window coordinate.
        This is mostly used internally when Select mode is activated
        Nc                 s   s   | ]}t |tr|V  qd S r+   r   r   rh   cr,   r,   r1   	<genexpr>  s    
z'Console.highlight_at.<locals>.<genexpr>c                 s   s   | ]}t |ts|V  qd S r+   r   r   r,   r,   r1   r     s    
)r   r   r   rv   pickrs   )r8   xyr@   Zwin_childrenr   r   r,   r,   r1   r     s    zConsole.highlight_atc                 G   s   || _ |sd| j_d S Nr   )r@   r   r   )r8   r@   largsr,   r,   r1   rs     s    zConsole.highlight_widgetc                 G   sV   | j s
d S | jd kr d| j_d S | jj| j_| j }| jj | krR|| j_d S r  )r   r@   r   r   Zget_window_matrixr   matrixget)r8   r   r  r,   r,   r1   r     s    

zConsole.update_widget_graphicsc                 C   s^   d}t |dr|js|S |||rZ|}|||\}}t|jD ]}| |||pV|}qB|S )z4Pick a widget at x/y, given a root `widget`
        Nvisible)hasattrr  r   Zto_localrv   r   r   )r8   r@   r  r  r   Zx2y2r   r,   r,   r1   r     s    zConsole.pickc                 C   s   |r|    n|   d S r+   )_activate_console_deactivate_console)r8   r[   r   r,   r,   r1   on_activated  s    
zConsole.on_activatedc                 C   s@   | | j jkr| j |  d| _| jD ]}|  q$td d S )Nr	   zConsole: console activated)r   r   rw   r  r   rK   r   infor8   r   r,   r,   r1   r
    s    

zConsole._activate_consolec                 C   sF   | j D ]}|  qd| j_| j | _d | _d| _d | _t	
d d S )Nr   FzConsole: console deactivated)r   rL   r   r   r   r  r@   rU   r   r   r  r  r,   r,   r1   r    s    


zConsole._deactivate_consolec                 G   sB  |d }|dkr4|dgkr4| j  | _ | j r0d| _dS |dkr\| jrLd| _dS | j r\d| _ dS | j rh| jsld S |dkr| jj| _n|dkrd	d
 | jjD }|r|d | _n|dkr| jj}dd
 |jD }|| j}td|d }|| | _nN|dkr>| jj}dd
 |jD }|| j}tt|d |d }|| | _d S )Nr   e   ZctrlT   Fi  i  c                 S   s   g | ]}t |ts|qS r,   r   r   r   r,   r,   r1   ri     s    
z-Console.keyboard_shortcut.<locals>.<listcomp>r	   i  c                 S   s   g | ]}t |ts|qS r,   r  r   r,   r,   r1   ri     s    
rk   i  c                 S   s   g | ]}t |ts|qS r,   r  r   r,   r,   r1   ri     s    
)	r   rU   r@   ru   r   ro   maxminlen)r8   r   Zscancoder  	modifiersZfiltered_childrenru   ro   r,   r,   r1   keyboard_shortcut  sB    

zConsole.keyboard_shortcut)F)N)'r<   r=   r>   rB   rS   r]   r   r   r{   r   r$   moder   r@   r    rU   r   rE   r   classmethodr   rQ   r   r   r   r   r   r   r   r   r   rs   r   r   r  r
  r  r  rM   r,   r,   rH   r1   r     s@   	   



r   c                 G   s&   t | d|_| j|jj|jjd d S )N)r   r   Zon_keyboard)r   rF   r;   r   r  )r   ctxr   r,   r,   r1   r     s    
r   c                 C   s   t tt| | dS )a  Create an Console instance attached to the *ctx* and bound to the
    Window's :meth:`~kivy.core.window.WindowBase.on_keyboard` event for
    capturing the keyboard shortcut.

        :Parameters:
            `win`: A :class:`Window <kivy.core.window.WindowBase>`
                The application Window to bind to.
            `ctx`: A :class:`~kivy.uix.widget.Widget` or subclass
                The Widget to be inspected.

    N)r)   Zschedule_oncer
   r   r   r  r,   r,   r1   r     s    r   c                 C   s4   t |dr0| j|jj|jjd | |j |`dS )z:Stop and unload any active Inspectors for the given *ctx*.rF   r  N)r  r   rF   r   r  r   r  r,   r,   r1   r     s    

r   )RrB   __all__Zkivyrequirerq   	functoolsr
   	itertoolsr   Zkivy.loggerr   Zkivy.uix.widgetr   Zkivy.uix.buttonr   Zkivy.uix.togglebuttonr   Zkivy.uix.labelr   Zkivy.uix.textinputr   Zkivy.uix.imager   Zkivy.uix.treeviewr   r   Zkivy.uix.gridlayoutr   Zkivy.uix.relativelayoutr   Zkivy.uix.boxlayoutr   Zkivy.uix.modalviewr   Zkivy.graphicsr   r   r   r   Z"kivy.graphics.context_instructionsr   Zkivy.graphics.transformationr   Zkivy.propertiesr   r    r!   r"   r#   r$   r%   r&   r'   Zkivy.graphics.texturer(   Z
kivy.clockr)   Z	kivy.langr*   load_stringr3   r4   r   r   r   rC   objectr   rN   rS   r]   rg   r{   r   r   r   r   r   r   r   r   r   r,   r,   r,   r1   <module>   sd   ~
,
|
* "6/  